Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
469 additions
and
4 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
src/app/components/editors/item/item-template/item-template.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<app-top-bar [handler]="handlerService"></app-top-bar> | ||
|
||
<div class="container-fluid"> | ||
|
||
<span *ngIf="editorService.loading">Loading...</span> | ||
|
||
<div *ngIf="editorService.form && !!editorService.loadedEntityId && !editorService.loading"> | ||
|
||
<app-query-output [editorService]="editorService" (executeQuery)="editorService.save($event)"></app-query-output> | ||
|
||
<hr class="mt-2 mb-1"> | ||
|
||
<div class="wiki-link"> | ||
<a [href]="docUrl" target="_blank"> | ||
<i class="fas fa-link"></i> {{ editorService.entityTable }} documentation | ||
</a> | ||
</div> | ||
|
||
<form | ||
[formGroup]="editorService.form" | ||
class="form-group edit-form" | ||
> | ||
|
||
</form> | ||
|
||
</div> | ||
</div> |
Empty file.
22 changes: 22 additions & 0 deletions
22
src/app/components/editors/item/item-template/item-template.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { Component } from '@angular/core'; | ||
|
||
import { SingleRowEditorComponent } from '../../shared/single-row-editor.component'; | ||
import { ItemTemplate } from '../../../../types/item-template.type'; | ||
import { ItemTemplateService } from '../../../../services/editors/item/item-template.service'; | ||
import { ItemHandlerService } from '../../../../services/handlers/item-handler.service'; | ||
|
||
@Component({ | ||
selector: 'app-item-template', | ||
templateUrl: './item-template.component.html', | ||
styleUrls: ['./item-template.component.scss'] | ||
}) | ||
export class ItemTemplateComponent extends SingleRowEditorComponent<ItemTemplate> { | ||
|
||
/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690 | ||
constructor( | ||
public editorService: ItemTemplateService, | ||
public handlerService: ItemHandlerService, | ||
) { | ||
super(editorService, handlerService); | ||
} | ||
} |
Empty file.
31 changes: 31 additions & 0 deletions
31
src/app/components/editors/item/item-template/item-template.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
import { ReactiveFormsModule } from '@angular/forms'; | ||
import { TooltipModule } from 'ngx-bootstrap'; | ||
|
||
import { TopBarModule } from '../../shared/top-bar/top-bar.module'; | ||
import { QueryOutputModule } from '../../shared/query-output/query-output.module'; | ||
import { ItemTemplateComponent } from './item-template.component'; | ||
import { SingleValueSelectorModule } from '../../shared/selectors/single-value-selector/single-value-selector.module'; | ||
import { FlagsSelectorModule } from '../../shared/selectors/flags-selector/flags-selector.module'; | ||
import { ItemSelectorModule } from '../../shared/selectors/item-selector/item-selector.module'; | ||
|
||
@NgModule({ | ||
declarations: [ | ||
ItemTemplateComponent, | ||
], | ||
imports: [ | ||
BrowserModule, | ||
ReactiveFormsModule, | ||
TopBarModule, | ||
QueryOutputModule, | ||
TooltipModule.forRoot(), | ||
SingleValueSelectorModule, | ||
FlagsSelectorModule, | ||
ItemSelectorModule, | ||
], | ||
exports: [ | ||
ItemTemplateComponent, | ||
], | ||
}) | ||
export class ItemTemplateModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
src/app/components/editors/item/select-item/select-item.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
<app-top-bar [handler]="handlerService"></app-top-bar> | ||
|
||
<div class="container-fluid p-3"> | ||
|
||
<app-create | ||
[entityTable]="entityTable" | ||
[entityIdField]="entityIdField" | ||
[customStartingId]="customStartingId" | ||
[handlerService]="handlerService" | ||
[queryService]="queryService" | ||
></app-create> | ||
|
||
<hr class="mt-2 mb-2"> | ||
|
||
<p>Or search and select an existing one:</p> | ||
<form [formGroup]="selectService.queryForm"> | ||
<div class="row"> | ||
<ng-container [formGroup]="selectService.fields"> | ||
<div class="form-group col-2"> | ||
<input [formControlName]="'entry'" type="number" class="form-control form-control-sm" id="search-id" placeholder="Item ID"> | ||
</div> | ||
<div class="form-group col-3"> | ||
<input [formControlName]="'name'" class="form-control form-control-sm" id="name" placeholder="Item name"> | ||
</div> | ||
</ng-container> | ||
<div class="form-group col-2"> | ||
<input [formControlName]="'limit'" class="form-control form-control-sm" id="limit" placeholder="Limit"> | ||
</div> | ||
<div class="col-2"> | ||
<button | ||
class="btn btn-primary btn-sm" | ||
id="search-btn" | ||
[disabled]="selectService.queryForm.invalid" | ||
(click)="selectService.onSearch()" | ||
>Search</button> | ||
</div> | ||
</div> | ||
<code [highlight]="selectService.query"></code> | ||
</form> | ||
|
||
<div *ngIf="selectService.rows"> | ||
|
||
<ngx-datatable | ||
class="bootstrap table table-striped text-center datatable-select" | ||
[rows]="selectService.rows" | ||
[headerHeight]="DTCFG.headerHeight" | ||
[footerHeight]="DTCFG.footerHeight" | ||
[columnMode]="DTCFG.columnMode" | ||
[rowHeight]="DTCFG.rowHeight" | ||
[limit]="DTCFG.limit" | ||
[selectionType]="DTCFG.selectionType" | ||
(select)='selectService.onSelect($event)' | ||
[count]="false" | ||
> | ||
<ngx-datatable-column name="ID" prop="ID" [minWidth]="100"> | ||
<ng-template let-row="row" ngx-datatable-cell-template> | ||
{{ row.entry }} | ||
</ng-template> | ||
</ngx-datatable-column> | ||
<ngx-datatable-column name="name" prop="name" [minWidth]="60"></ngx-datatable-column> | ||
</ngx-datatable> | ||
|
||
</div> | ||
</div> |
Empty file.
35 changes: 35 additions & 0 deletions
35
src/app/components/editors/item/select-item/select-item.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { Component, } from '@angular/core'; | ||
|
||
import { SelectComponent } from '../../shared/select.component'; | ||
import { | ||
ITEM_TEMPLATE_CUSTOM_STARTING_ID, | ||
ITEM_TEMPLATE_ID, | ||
ITEM_TEMPLATE_TABLE, | ||
ItemTemplate | ||
} from '../../../../types/item-template.type'; | ||
import { ItemSelectService } from '../../../../services/select/item-select.service'; | ||
import { ItemHandlerService } from '../../../../services/handlers/item-handler.service'; | ||
import { QueryService } from '../../../../services/query.service'; | ||
|
||
@Component({ | ||
selector: 'app-select-item', | ||
templateUrl: './select-item.component.html', | ||
styleUrls: ['./select-item.component.scss'] | ||
}) | ||
export class SelectItemComponent extends SelectComponent<ItemTemplate> { | ||
/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690 | ||
constructor( | ||
public selectService: ItemSelectService, | ||
public handlerService: ItemHandlerService, | ||
public queryService: QueryService, | ||
) { | ||
super( | ||
ITEM_TEMPLATE_TABLE, | ||
ITEM_TEMPLATE_ID, | ||
ITEM_TEMPLATE_CUSTOM_STARTING_ID, | ||
selectService, | ||
handlerService, | ||
queryService, | ||
); | ||
} | ||
} |
170 changes: 170 additions & 0 deletions
170
src/app/components/editors/item/select-item/select-item.integration.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { RouterTestingModule } from '@angular/router/testing'; | ||
import { Router } from '@angular/router'; | ||
import { of } from 'rxjs'; | ||
import Spy = jasmine.Spy; | ||
|
||
import { QueryService } from '../../../../services/query.service'; | ||
import { SelectItemComponent } from './select-item.component'; | ||
import { ItemSelectService } from '../../../../services/select/item-select.service'; | ||
import { SelectItemModule } from './select-item.module'; | ||
import { ItemTemplate } from '../../../../types/item-template.type'; | ||
import { SelectPageObject } from '../../../../test-utils/select-page-object'; | ||
|
||
class SelectItemComponentPage extends SelectPageObject<SelectItemComponent> { | ||
ID_FIELD = 'entry'; | ||
} | ||
|
||
describe('SelectItem integration tests', () => { | ||
let component: SelectItemComponent; | ||
let fixture: ComponentFixture<SelectItemComponent>; | ||
let selectService: ItemSelectService; | ||
let page: SelectItemComponentPage; | ||
let queryService: QueryService; | ||
let querySpy: Spy; | ||
let navigateSpy: Spy; | ||
|
||
const value = 1200; | ||
|
||
beforeEach(async(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [ | ||
SelectItemModule, | ||
RouterTestingModule, | ||
], | ||
}) | ||
.compileComponents(); | ||
})); | ||
|
||
beforeEach(() => { | ||
navigateSpy = spyOn(TestBed.get(Router), 'navigate'); | ||
queryService = TestBed.get(QueryService); | ||
querySpy = spyOn(queryService, 'query').and.returnValue(of( | ||
{ results: [{ max: 1 }] } | ||
)); | ||
|
||
selectService = TestBed.get(ItemSelectService); | ||
|
||
fixture = TestBed.createComponent(SelectItemComponent); | ||
page = new SelectItemComponentPage(fixture); | ||
component = fixture.componentInstance; | ||
fixture.autoDetectChanges(true); | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should correctly initialise', async(() => { | ||
fixture.whenStable().then(() => { | ||
expect(page.createInput.value).toEqual(`${component.customStartingId}`); | ||
page.expectNewEntityFree(); | ||
expect(querySpy).toHaveBeenCalledWith( | ||
'SELECT MAX(entry) AS max FROM item_template;' | ||
); | ||
expect(page.queryWrapper.innerText).toContain( | ||
'SELECT * FROM `item_template` LIMIT 100' | ||
); | ||
}); | ||
})); | ||
|
||
it('should correctly behave when inserting and selecting free id', async(() => { | ||
fixture.whenStable().then(() => { | ||
querySpy.calls.reset(); | ||
querySpy.and.returnValue(of( | ||
{ results: [] } | ||
)); | ||
|
||
page.setInputValue(page.createInput, value); | ||
|
||
expect(querySpy).toHaveBeenCalledTimes(1); | ||
expect(querySpy).toHaveBeenCalledWith( | ||
`SELECT * FROM \`item_template\` WHERE (entry = ${value})` | ||
); | ||
page.expectNewEntityFree(); | ||
|
||
page.clickElement(page.selectNewBtn); | ||
|
||
expect(navigateSpy).toHaveBeenCalledTimes(1); | ||
expect(navigateSpy).toHaveBeenCalledWith(['item/item-template']); | ||
page.expectTopBarCreatingNew(value); | ||
}); | ||
})); | ||
|
||
it('should correctly behave when inserting an existing entity', async(() => { | ||
fixture.whenStable().then(() => { | ||
querySpy.calls.reset(); | ||
querySpy.and.returnValue(of( | ||
{ results: ['mock value'] } | ||
)); | ||
|
||
page.setInputValue(page.createInput, value); | ||
|
||
expect(querySpy).toHaveBeenCalledTimes(1); | ||
expect(querySpy).toHaveBeenCalledWith( | ||
`SELECT * FROM \`item_template\` WHERE (entry = ${value})` | ||
); | ||
page.expectEntityAlreadyInUse(); | ||
}); | ||
})); | ||
|
||
for (const { testId, id, name, limit, expectedQuery } of [ | ||
{ | ||
testId: 1, id: 1200, name: `The People's Militia`, limit: '100', expectedQuery: | ||
'SELECT * FROM `item_template` WHERE (`entry` LIKE \'%1200%\') AND (`name` LIKE \'%The People\\\'s Militia%\') LIMIT 100' | ||
}, | ||
{ | ||
testId: 2, id: '', name: `The People's Militia`, limit: '100', expectedQuery: | ||
'SELECT * FROM `item_template` WHERE (`name` LIKE \'%The People\\\'s Militia%\') LIMIT 100' | ||
}, | ||
{ | ||
testId: 3, id: '', name: `The People's Militia`, limit: '100', expectedQuery: | ||
'SELECT * FROM `item_template` WHERE (`name` LIKE \'%The People\\\'s Militia%\') LIMIT 100' | ||
}, | ||
{ | ||
testId: 4, id: 1200, name: '', limit: '', expectedQuery: | ||
'SELECT * FROM `item_template` WHERE (`entry` LIKE \'%1200%\')' | ||
}, | ||
]) { | ||
it(`searching an existing entity should correctly work [${testId}]`, () => { | ||
querySpy.calls.reset(); | ||
if (id) { | ||
page.setInputValue(page.searchIdInput, id); | ||
} | ||
if (name) { | ||
page.setInputValue(page.searchNameInput, name); | ||
} | ||
page.setInputValue(page.searchLimitInput, limit); | ||
|
||
expect(page.queryWrapper.innerText).toContain(expectedQuery); | ||
|
||
page.clickElement(page.searchBtn); | ||
|
||
expect(querySpy).toHaveBeenCalledTimes(1); | ||
expect(querySpy).toHaveBeenCalledWith(expectedQuery); | ||
}); | ||
} | ||
|
||
it('searching and selecting an existing entity from the datatable should correctly work', () => { | ||
const results: Partial<ItemTemplate>[] = [ | ||
{ id: 1, name: 'An awesome Item 1', ItemType: 0, ItemLevel: 1, MinLevel: 10, ItemDescription: '' }, | ||
{ id: 2, name: 'An awesome Item 2', ItemType: 0, ItemLevel: 2, MinLevel: 20, ItemDescription: '' }, | ||
{ id: 3, name: 'An awesome Item 3', ItemType: 0, ItemLevel: 3, MinLevel: 30, ItemDescription: '' }, | ||
]; | ||
querySpy.calls.reset(); | ||
querySpy.and.returnValue(of({ results })); | ||
|
||
page.clickElement(page.searchBtn); | ||
|
||
const row0 = page.getDatatableRow(page.DT_SELECTOR, 0); | ||
const row1 = page.getDatatableRow(page.DT_SELECTOR, 1); | ||
const row2 = page.getDatatableRow(page.DT_SELECTOR, 2); | ||
|
||
expect(row0.innerText).toContain(results[0].name); | ||
expect(row1.innerText).toContain(results[1].name); | ||
expect(row2.innerText).toContain(results[2].name); | ||
|
||
page.clickElement(page.getDatatableCell(page.DT_SELECTOR, 1, 1)); | ||
|
||
expect(navigateSpy).toHaveBeenCalledTimes(1); | ||
expect(navigateSpy).toHaveBeenCalledWith(['item/item-template']); | ||
page.expectTopBarEditing(results[1].entry, results[1].name); | ||
}); | ||
}); |
30 changes: 30 additions & 0 deletions
30
src/app/components/editors/item/select-item/select-item.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { NgModule } from '@angular/core'; | ||
import { BrowserModule } from '@angular/platform-browser'; | ||
import { ReactiveFormsModule } from '@angular/forms'; | ||
import { NgxDatatableModule } from '@swimlane/ngx-datatable'; | ||
import { HighlightModule } from 'ngx-highlightjs'; | ||
|
||
import { TopBarModule } from '../../shared/top-bar/top-bar.module'; | ||
import { QueryOutputModule } from '../../shared/query-output/query-output.module'; | ||
import { SelectItemComponent } from './select-item.component'; | ||
import { CreateModule } from '../../shared/create/create.module'; | ||
import { highlightOptions } from '../../../../config/highlight.config'; | ||
|
||
@NgModule({ | ||
declarations: [ | ||
SelectItemComponent, | ||
], | ||
imports: [ | ||
BrowserModule, | ||
ReactiveFormsModule, | ||
TopBarModule, | ||
QueryOutputModule, | ||
CreateModule, | ||
HighlightModule.forRoot(highlightOptions), | ||
NgxDatatableModule, | ||
], | ||
exports: [ | ||
SelectItemComponent, | ||
], | ||
}) | ||
export class SelectItemModule {} |
Oops, something went wrong.