Config-editor-ui: some css fixes + testing deployment + title validation + regex links (#200)

This commit is contained in:
Celie Valentiny
2021-03-01 16:35:29 +00:00
committed by GitHub Enterprise
parent 751552b475
commit 5d01ff81c7
40 changed files with 340 additions and 159 deletions

View File

@@ -7,7 +7,7 @@ import java.util.List;
@Attributes(title = "rule", description = "Rule for real-time alert matching")
public class RuleDto {
@JsonProperty("rule_name")
@Attributes(required = true, description = "Rule name that uniquely identifies the rule")
@Attributes(required = true, description = "Rule name that uniquely identifies the rule", pattern = "^[a-zA-Z0-9_\\-]+$")
private String ruleName;
@JsonProperty("rule_author")

View File

@@ -11,7 +11,7 @@ import java.util.List;
@Attributes(title = "test case", description = "Test case for testing configurations")
public class TestCaseDto {
@JsonProperty("test_case_name")
@Attributes(required = true, description = "The name of the test case")
@Attributes(required = true, description = "The name of the test case", pattern = "^[a-zA-Z0-9_\\-]+$")
private String testCaseName;
@Attributes(required = true, description = "Version of the test case")
private Integer version;

View File

@@ -1,7 +1,6 @@
{
"name": "rule-editor.ui",
"version": "2.0.17",
"siembolCompileTimeVersion": "1.65-SNAPSHOT",
"version": "2.0.18",
"license": "MIT",
"scripts": {
"ng": "ng",

View File

@@ -165,7 +165,7 @@ const DEV_PROVIDERS = [...PROD_PROVIDERS];
],
types: [
{ name: 'string', component: InputTypeComponent, wrappers: ['form-field'] },
{ name: 'textarea', component: TextAreaTypeComponent, wrappers: [] },
{ name: 'textarea', component: TextAreaTypeComponent, wrappers: ['form-field'] },
{ name: 'rawobject', component: JsonObjectTypeComponent, wrappers: ['form-field'] },
{
name: 'number',

View File

@@ -30,4 +30,4 @@ export function parseUrl(path: string): UrlInfo {
let testCaseName = url.searchParams.get("testCaseName");
return { service: service, mode: mode, configName: configName, testCaseName: testCaseName };
}
}

View File

@@ -3,4 +3,3 @@
<p>Version: {{data?.appVersion}}</p>
<p>Angular Version: {{data?.angularVersion}}</p>
<p>Build Date: {{data?.buildDate}}</p>
<p>Siembol Version: {{data?.siembolCompileTimeVersion}}</p>

View File

@@ -46,7 +46,11 @@
</ng-container>
<div mat-dialog-actions class="button-row">
<button mat-raised-button color="primary" [disabled]="!testEnabled || !isValid" (click)="onClickTest()">TEST</button>
<button mat-raised-button color="primary" [disabled]="!testEnabled || !isValid" (click)="onClickTest(testingDialog)">TEST</button>
<button mat-raised-button color="primary" [disabled]="!isValid" (click)="onClickDeploy()">DEPLOY</button>
<button mat-raised-button color="accent" (click)="onClickClose()">CANCEL</button>
</div>
</div>
<ng-template #testingDialog>
<re-config-testing [testingType]="testingType"></re-config-testing>
</ng-template>

View File

@@ -1,20 +1,20 @@
import { UiMetadataMap } from '../../model/ui-metadata-map';
import { Component, Inject } from '@angular/core';
import { Component, Inject, TemplateRef } from '@angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FormGroup } from '@angular/forms';
import { AppConfigService } from '@app/config';
import { EditorService } from '@services/editor.service';
import { ConfigData, Config, Deployment } from '@app/model';
import { ConfigData, Deployment } from '@app/model';
import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
import { FormlyJsonschema } from '@ngx-formly/core/json-schema';
import { cloneDeep } from 'lodash';
import { take, catchError } from 'rxjs/operators';
import { throwError, Observable, of } from 'rxjs';
import { throwError, of } from 'rxjs';
import { DiffResults } from 'ngx-text-diff/lib/ngx-text-diff.model';
import { AppService } from '@app/services/app.service';
import { DeploymentWrapper } from '@app/model/config-model';
import { DeploymentWrapper, TestingType } from '@app/model/config-model';
@Component({
selector: 're-deploy-dialog',
@@ -36,6 +36,7 @@ export class DeployDialogComponent {
serviceName: string;
uiMetadata: UiMetadataMap;
extrasData = {};
testingType = TestingType.DEPLOYMENT_TESTING;
testEnabled = false;
public options: FormlyFormOptions = {formState: {}};
@@ -45,7 +46,8 @@ export class DeployDialogComponent {
private readonly OUTDATED_DEPLOYMENT_MESSAGE = `Old version detected, latest deployment
have now been reloaded. Please prepare your deployment again.`;
private readonly INVALID_MESSAGE = 'Deployment is invalid.'
private readonly INVALID_MESSAGE = 'Deployment is invalid.';
private readonly MAX_HEIGHT = '90vh';
constructor(public dialogref: MatDialogRef<DeployDialogComponent>,
private config: AppConfigService,
@@ -133,8 +135,10 @@ export class DeployDialogComponent {
this.dialogref.close(deployment);
}
onClickTest() {
//TODO: add testing deployment
onClickTest(templateRef: TemplateRef<any>) {
this.dialog.open(templateRef, {
maxHeight: this.MAX_HEIGHT
})
}
onClickClose() {

View File

@@ -17,7 +17,7 @@
</re-generic-editor>
</mat-tab>
<mat-tab [label]="TESTING_TAB.name" [disabled]="!testingEnabled()">
<re-config-testing>
<re-config-testing [testingType]="testingType">
</re-config-testing>
</mat-tab>
<mat-tab [label]="TEST_CASE_TAB.name" [disabled]="!testCaseEnabled()">

View File

@@ -11,6 +11,7 @@ import { cloneDeep } from 'lodash';
import { Observable, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { EditorComponent } from '../editor/editor.component';
import { TestingType } from '@app/model/config-model';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -34,6 +35,7 @@ export class EditorViewComponent implements OnInit, OnDestroy {
schema: JSONSchema7;
selectedTab = this.NO_TAB;
previousTab = this.NO_TAB;
testingType = TestingType.CONFIG_TESTING;
fields: FormlyFieldConfig[] = [];

View File

@@ -2,7 +2,16 @@
<mat-card-title>
<div class="rule-title" *ngIf="config?.isNew; else: showTitle">
<mat-form-field>
<input matInput placeholder="Config name" [(ngModel)]="configName" name="Config name" />
<input
matInput
placeholder="Config name"
[(ngModel)]="configName"
name="Config name"
[formControl]="titleFormControl"
/>
<mat-error
*ngIf="titleFormControl.hasError('pattern')">Please enter a valid name
</mat-error>
</mat-form-field>
</div>
<ng-template #showTitle>
@@ -21,7 +30,7 @@
</form>
</mat-card-content>
<mat-card-actions align="end">
<button class="submit-button" mat-raised-button color="accent" type="submit" [disabled]="!form.valid"
<button class="submit-button" mat-raised-button color="accent" type="submit" [disabled]="!form.valid || titleFormControl.hasError('pattern')"
(click)="onSubmit()">
Submit
</button>

View File

@@ -1,8 +1,8 @@
import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { EditorService } from '@services/editor.service';
import { ConfigData, Config } from '@app/model';
import { ConfigData, Config, NAME_REGEX } from '@app/model';
import { Type } from '@app/model/config-model';
import { PopupService } from '@app/popup.service';
import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
@@ -19,6 +19,10 @@ import { SubmitDialogComponent } from '../submit-dialog/submit-dialog.component'
templateUrl: './editor.component.html',
})
export class EditorComponent implements OnInit, OnDestroy {
titleFormControl = new FormControl('', [
Validators.pattern(NAME_REGEX)
]);
public ngUnsubscribe = new Subject();
public configName: string;
public configData: ConfigData = {};

View File

@@ -36,4 +36,4 @@
</mat-grid-tile>
</mat-grid-list>
</mat-expansion-panel>
</div>
</div>

View File

@@ -41,4 +41,4 @@
margin-left: auto !important;
margin-right: auto !important;
transform: scale(1.5);
}
}

View File

@@ -13,7 +13,6 @@
}
img {
display: block;
height: 100%;
margin-top: 0px;
margin-bottom: 0px;
}
@@ -48,8 +47,8 @@
.logo {
min-width: 105px;
height: 100%;
padding: 0 0px;
height: 100%;
}
.env {

View File

@@ -1,9 +1,9 @@
import { ChangeDetectionStrategy, Component, OnInit, ViewChild, ChangeDetectorRef } from '@angular/core';
import { ChangeDetectionStrategy, Component, OnInit, ViewChild, ChangeDetectorRef, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { EditorService } from '@app/services/editor.service';
import { FormlyFieldConfig, FormlyFormOptions } from '@ngx-formly/core';
import { FormlyForm } from '@ngx-formly/core';
import { ConfigTestResult } from '../../../model/config-model';
import { ConfigTestResult, TestingType } from '../../../model/config-model';
import { take } from 'rxjs/operators';
import { FormlyJsonschema } from '@ngx-formly/core/json-schema';
@@ -23,6 +23,7 @@ export class ConfigTestingComponent implements OnInit {
rawObjects: {}
}
};
@Input() testingType: TestingType;
@ViewChild('formly', { static: true }) formly: FormlyForm;
public form: FormGroup = new FormGroup({});
public isInvalid = false;
@@ -44,13 +45,13 @@ export class ConfigTestingComponent implements OnInit {
runTest() {
const cleanedTestSpecification = this.editorService.configSchema
.cleanRawObjects(this.form.value, this.formly.options.formState.rawObjects);
this.editorService.configStore.testService.testEditedConfig(cleanedTestSpecification).pipe(take(1))
this.editorService.configStore.testService.test(cleanedTestSpecification, this.testingType).pipe(take(1))
.subscribe((r: ConfigTestResult) => {
this.output = r;
this.isInvalid = r !== undefined ? false : true;
this.cd.markForCheck();
}
);
)
}
}

View File

@@ -65,7 +65,6 @@ export class TestCaseEditorComponent implements OnInit, OnDestroy {
this.testCaseWrapper = testCaseWrapper;
this.testCase = testCaseWrapper !== null ? cloneDeep(this.testCaseWrapper.testCase) : {};
this.form = new FormGroup({});
this.options.formState = {
mainModel: this.testCase,
rawObjects: {},
@@ -101,7 +100,8 @@ export class TestCaseEditorComponent implements OnInit, OnDestroy {
relativeTo: this.activeRoute,
queryParams: {
testCaseName: currentTestCase.testCase.test_case_name,
newTestCase: null
newTestCase: null,
cloneTestCase: null
},
queryParamsHandling: 'merge',
}

View File

@@ -5,7 +5,6 @@ export interface BuildInfo {
appVersion: number;
buildDate: Date;
angularVersion: string;
siembolCompileTimeVersion: string;
}
export enum AuthenticationType {

View File

@@ -2,6 +2,8 @@ import { TestCase, TestCaseWrapper, TestCaseEvaluationResult } from './test-case
import { JSONSchema7 } from 'json-schema';
import { Observable } from 'rxjs';
export const NAME_REGEX = "^[a-zA-Z0-9_\\-]+$";
export const repoNames = {
store_directory_name: "Config Store Folder",
release_directory_name: "Config Deployment Folder",
@@ -9,6 +11,10 @@ export const repoNames = {
admin_config_store_directory_name: "Admin Config Folder"
}
export enum TestingType {
DEPLOYMENT_TESTING = 'deployment_testing',
CONFIG_TESTING = 'config_testing'
}
export enum Type {
CONFIG_TYPE = 'Config',

View File

@@ -1,6 +1,6 @@
export {
GitFiles, SchemaInfo, Content,
PullRequestInfo, Config, ConfigData, Deployment,
RepositoryLinks, RepositoryLinksWrapper, FileHistory
RepositoryLinks, RepositoryLinksWrapper, FileHistory, NAME_REGEX
} from './config-model';
export { BuildInfo, AuthenticationType, AppConfig } from './app-config';

View File

@@ -7,7 +7,11 @@ import { FieldArrayType } from '@ngx-formly/core';
selector: 'formly-array-type',
template: `
<legend *ngIf="to.label">{{ to.label }}</legend>
<p class="description" *ngIf="to.description">{{ to.description }}</p>
<p class="description" *ngIf="to.description">{{ to.description }}
<ng-container matSuffix *ngIf="to.suffix">
<ng-container *ngTemplateOutlet="to.suffix"></ng-container>
</ng-container>
</p>
<div class="alert alert-danger" role="alert" *ngIf="showError && formControl.errors">
<formly-validation-message [field]="field"></formly-validation-message>
</div>
@@ -46,6 +50,8 @@ import { FieldArrayType } from '@ngx-formly/core';
padding: 0 10px 10px 15px;
font-size: 0.9em;
color: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: space-between;
}
.row {

View File

@@ -9,7 +9,12 @@ import { PopupService } from '@app/popup.service';
template: `
<ng-container #fieldComponent></ng-container>
<ng-template #matSuffix>
<button mat-icon-button matToolTipClass="link-tooltip" [matTooltip]="to.link" (click)="onClick()" (contextmenu)="onRightClick()">
<button
*ngIf="to.showHelpLink != false"
mat-icon-button matToolTipClass="link-tooltip"
[matTooltip]="to.link"
(click)="onClick()"
(contextmenu)="onRightClick()">
<mat-icon>{{ suffixIcon }}</mat-icon>
</button>
</ng-template>
@@ -33,11 +38,7 @@ export class HelpLinkWrapperComponent extends FieldWrapper implements AfterViewI
if (this.matSuffix ) {
setTimeout(() => this.to.suffix = this.matSuffix);
}
if (!this.to.suffixIcon) {
this.suffixIcon = "help_outline";
} else {
this.suffixIcon = this.to.suffixIcon;
}
this.suffixIcon = this.to.suffixIcon ? this.to.suffixIcon : "help_outline";
}
onClick() {

View File

@@ -28,7 +28,7 @@ import { FieldType } from '@ngx-formly/material/form-field';
.highlighted-overlay {
position: absolute;
top: 5px;
top: 6px;
}
`]
})

View File

@@ -8,12 +8,8 @@ import { FieldWrapper } from '@ngx-formly/core';
template: `
<mat-card>
<mat-card-header>
<mat-card-title>
{{ to.label }}
</mat-card-title>
</mat-card-header>
<mat-card-content>
<p class="description" *ngIf="to.description">{{ to.description }}</p>
<ng-container #fieldComponent></ng-container>
</mat-card-content>
<mat-card>

View File

@@ -10,38 +10,35 @@ import { take } from 'rxjs/operators';
// tslint:disable-next-line:component-selector
selector: 'formly-field-mat-textarea',
template: `
<div class="overlay-holder">
<mat-form-field #formfield>
<mat-label>{{ to.label }}</mat-label>
<textarea class="text-area" highlight matInput #textbox cdkTextareaAutosize #autosize="cdkTextareaAutosize"
spellcheck="false"
[class.hide-text]="true"
[id]="id"
[name]="to.title"
[readonly]="to.readonly"
[formControl]="formControl"
[errorStateMatcher]="errorStateMatcher"
[formlyAttributes]="field"
[placeholder]="to.placeholder"
[tabindex]="to.tabindex || 0"
[readonly]="to.readonly"
>
</textarea>
<mat-hint *ngIf="to?.description && (!to?.errorMessage)"
align="end" [innerHTML]="to?.description"></mat-hint>
</mat-form-field>
<div class="highlighted-overlay" [class.show-overlay]="true" [innerHtml]="value | highlightVariables"></div>
</div>
<textarea
class="text-area"
highlight
matInput
cdkTextareaAutosize
spellcheck="false"
[class.hide-text]="true"
[id]="id"
[name]="to.title"
[readonly]="to.readonly"
[formControl]="formControl"
[errorStateMatcher]="errorStateMatcher"
[formlyAttributes]="field"
[placeholder]="to.placeholder"
[tabindex]="to.tabindex || 0"
[readonly]="to.readonly"
>
</textarea>
<div
class="highlighted-overlay"
[innerHtml]="value | highlightVariables">
</div>
`,
styles: [`
.text-area {
resize: none;
line-height: normal;
overflow: hidden;
}
mat-form-field {
width: 100%;
margin: 0;
}
.hide-text {
@@ -57,44 +54,13 @@ import { take } from 'rxjs/operators';
.highlighted-overlay {
position: absolute;
top: 21px;
left: 0;
z-index: 10;
}
.overlay-holder {
position: relative;
line-height: normal;
overflow: hidden;
}
::ng-deep .overlay-holder .mat-input-element {
position: relative;
z-index: 20;
top: 5.5px;
left: 0;
z-index: 10;
}
`],
})
export class TextAreaTypeComponent extends FieldType implements OnDestroy, AfterViewInit {
@ViewChild(MatInput, {static: false}) formFieldControl!: MatInput;
@ViewChild('textbox', {static: true}) textbox: ElementRef;
@ViewChild('formfield', {static: true}) formfield: FormControl;
@ViewChild('autosize', {static: false}) autosize: CdkTextareaAutosize;
public displayOverlay = true;
private ngUnsubscribe: Subject<any> = new Subject();
constructor(private ngZone: NgZone) {
super();
}
triggerResize() {
this.ngZone.onStable.pipe(take(1)).subscribe(() => this.autosize.resizeToFitContent(true));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
export class TextAreaTypeComponent extends FieldType implements AfterViewInit {
@ViewChild(MatInput, {static: true}) formFieldControl!: MatInput;
}

View File

@@ -378,9 +378,16 @@ export class ConfigLoaderService {
);
}
public testDeploymentConfig(
testDto: ConfigTestDto
): Observable<ConfigTestResult> {
public testDeploymentConfig(deployment: Deployment, testSpecification: any): Observable<ConfigTestResult> {
const testDto: ConfigTestDto = {
files: [
{
content: deployment
}
],
test_specification: testSpecification
};
testDto.files[0].content = this.marshalDeploymentFormat(
testDto.files[0].content
);

View File

@@ -3,7 +3,7 @@ import { ConfigStoreState } from "../model/store-state";
import { ConfigLoaderService } from "./config-loader.service";
import { TestCaseWrapper, TestCaseResult, TestCaseMap, isNewTestCase } from "../model/test-case";
import { ConfigStoreStateBuilder } from "./config-store-state.builder";
import { ConfigTestResult } from "../model/config-model";
import { ConfigTestResult, TestingType } from "../model/config-model";
import { cloneDeep } from 'lodash';
@@ -180,6 +180,13 @@ export class TestStoreService {
return this.configLoaderService.validateTestCase(testCase.testCase);
}
test(testSpecification: any, type: TestingType): Observable<ConfigTestResult> {
if (type == TestingType.CONFIG_TESTING) {
return this.testEditedConfig(testSpecification);
}
return this.testDeployment(testSpecification);
}
testEditedConfig(testSpecification: any): Observable<ConfigTestResult> {
const config = this.store.getValue().editedConfig;
if (!config) {
@@ -188,4 +195,9 @@ export class TestStoreService {
return this.configLoaderService.testSingleConfig(config.configData, testSpecification);
}
testDeployment(testSpecification: any): Observable<ConfigTestResult> {
const deployment = this.store.getValue().deployment;
return this.configLoaderService.testDeploymentConfig(deployment, testSpecification);
}
}

View File

@@ -38,3 +38,4 @@ body {
font-family: Roboto, "Helvetica Neue", sans-serif;
background: #303030;
}

View File

@@ -10,8 +10,7 @@
"$..rule_description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
@@ -44,7 +43,13 @@
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
},
"expressionProperties": {
"templateOptions.showHelpLink": "model.matcher_type !== 'IS_IN_SET'"
}
}
}
}

View File

@@ -10,8 +10,7 @@
"$..rule_description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},

View File

@@ -10,8 +10,7 @@
"$..rule_description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
@@ -48,6 +47,20 @@
"hideExpression": "model.matcher_type !== 'IS_IN_SET'"
}
}
},
"$..data": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
},
"expressionProperties": {
"templateOptions.showHelpLink": "model.matcher_type !== 'IS_IN_SET'"
}
}
}
}
},
"admin_config_layout": {

View File

@@ -47,7 +47,14 @@
"$..parser_extractors..regular_expressions": {
"widget": {
"formlyConfig": {
"hideExpression": "field.parent.parent.model.extractor_type !== 'pattern_extractor'"
"hideExpression": "field.parent.parent.model.extractor_type !== 'pattern_extractor'",
"wrappers": [
"help-link",
"panel"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
@@ -243,24 +250,6 @@
}
}
},
"$..transformations..fields_filter..including_fields": {
"widget": {
"formlyConfig": {
"wrappers": [
"panel"
]
}
}
},
"$..transformations..fields_filter..excluding_fields": {
"widget": {
"formlyConfig": {
"wrappers": [
"panel"
]
}
}
},
"$..transformations..string_replace_target": {
"widget": {
"formlyConfig": {
@@ -300,14 +289,101 @@
"hideExpression": "!(field.parent.parent.model.transformation_type === 'field_name_change_case')"
}
}
},
"$..attributes..time_formats": {
"widget": {
"formlyConfig": {
"wrappers": [
"expansion-panel"
],
"hideExpression": "!(field.parent.parent.model.post_processing_functions && field.parent.parent.model.post_processing_functions.includes('format_timestamp'))"
}
}
},
"$..attributes..time_format": {
"widget": {
"formlyConfig": {
"wrappers": [
"form-field",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html"
}
}
}
},
"$..attributes..validation_regex": {
"widget": {
"formlyConfig": {
"wrappers": [
"form-field",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..attributes..patterns..pattern": {
"widget": {
"formlyConfig": {
"wrappers": [
"form-field",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..transformations..including_fields": {
"widget": {
"formlyConfig": {
"wrappers": [
"help-link",
"panel"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..transformations..excluding_fields": {
"widget": {
"formlyConfig": {
"wrappers": [
"panel",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..transformations..message_filter..pattern": {
"widget": {
"formlyConfig": {
"wrappers": [
"form-field",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
}
},
"test_layout": {
"$..properties.log": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
}

View File

@@ -10,8 +10,7 @@
"$..parsing_app_description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
@@ -58,6 +57,19 @@
"hideExpression": "!model.parse_metadata"
}
}
},
"$..routing_field_pattern": {
"widget": {
"formlyConfig": {
"wrappers": [
"form-field",
"help-link"
],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
}
},
"admin_config_layout": {

View File

@@ -10,8 +10,7 @@
"$..rule_description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
@@ -19,7 +18,73 @@
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
},
"expressionProperties": {
"templateOptions.showHelpLink": "model.matcher_type !== 'IS_IN_SET'"
}
}
}
},
"$..oneOf[?(@.title == 'array_markdown_table_formatter')]..including_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..oneOf[?(@.title == 'array_markdown_table_formatter')]..excluding_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..oneOf[?(@.title == 'array_reducer')]..properties.including_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..oneOf[?(@.title == 'array_reducer')]..excluding_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..oneOf[?(@.title == 'markdown_table_formatter')]..including_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},
"$..oneOf[?(@.title == 'markdown_table_formatter')]..excluding_fields": {
"widget": {
"formlyConfig": {
"wrappers": ["form-field", "help-link"],
"templateOptions": {
"link": "https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html"
}
}
}
},

View File

@@ -31,8 +31,7 @@
"properties.description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
@@ -48,24 +47,21 @@
"$..json_path": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
"$..expected_pattern": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
},
"$..assertions..properties.description": {
"widget": {
"formlyConfig": {
"type": "textarea",
"wrappers": []
"type": "textarea"
}
}
}

View File

@@ -16,7 +16,7 @@
"labelsFunc": "const ret = []; if (model.evaluators && model.evaluators.length > 0){for(const e of model.evaluators) {ret.push(e.evaluator_type);} } return ret;",
"testing": {
"perConfigTestEnabled": true,
"deploymentTestEnabled": false,
"deploymentTestEnabled": true,
"testCaseEnabled": false
}
},
@@ -37,7 +37,7 @@
"labelsFunc": "const ret = ['SourceType:' + model.source_type]; if (model.tags !== undefined) { ret.push(...model.tags.map(t => t.tag_name + ':' + t.tag_value));} return ret;",
"testing": {
"perConfigTestEnabled": true,
"deploymentTestEnabled": false,
"deploymentTestEnabled": true,
"testCaseEnabled": true
}
},

View File

@@ -7,7 +7,7 @@ import java.util.List;
@Attributes(title = "rule", description = "Rule for real-time enriching events")
public class RuleDto {
@JsonProperty("rule_name")
@Attributes(required = true, description = "Rule name that uniquely identifies the rule")
@Attributes(required = true, description = "Rule name that uniquely identifies the rule", pattern = "^[a-zA-Z0-9_\\-]+$")
private String ruleName;
@JsonProperty("rule_author")

View File

@@ -5,7 +5,7 @@ import com.github.reinert.jjschema.Attributes;
@Attributes(title = "parsing application", description = "Parser application specification")
public class ParsingApplicationDto {
@JsonProperty("parsing_app_name")
@Attributes(required = true, description = "The name of the parsing application")
@Attributes(required = true, description = "The name of the parsing application", pattern = "^[a-zA-Z0-9_\\-]+$")
private String parsingApplicationName;
@JsonProperty("parsing_app_version")

View File

@@ -6,7 +6,7 @@ import java.util.List;
@Attributes(title = "parser config", description = "Parser specification")
public class ParserConfigDto {
@JsonProperty("parser_name")
@Attributes(required = true, description = "Name of the parser")
@Attributes(required = true, description = "Name of the parser", pattern = "^[a-zA-Z0-9_\\-]+$")
private String parserName;
@JsonProperty("parser_version")

View File

@@ -8,7 +8,7 @@ import java.util.List;
@Attributes(title = "rule", description = "Response rule that should handle response to a siembol alert")
public class RuleDto {
@JsonProperty("rule_name")
@Attributes(required = true, description = "ResponseRule name that uniquely identifies the rule")
@Attributes(required = true, description = "ResponseRule name that uniquely identifies the rule", pattern = "^[a-zA-Z0-9_\\-]+$")
private String ruleName;
@JsonProperty("rule_author")