Skip to content

Commit

Permalink
feat: implement quest-selector (#546)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancescoBorzi committed Mar 29, 2020
1 parent cfca29c commit c8c3f37
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 0 deletions.
Expand Up @@ -218,6 +218,11 @@
</div>
<div class="form-group col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
<label class="control-label" for="startquest">startquest</label>
<keira-quest-selector-btn
[control]="editorService.form.controls.startquest"
[config]="{ name: 'startquest' }"
[modalClass]="'modal-lg'"
></keira-quest-selector-btn>
<i
class="fas fa-info-circle ml-1" [placement]="'auto'"
[tooltip]="'The ID of the quest that this item will start if right-clicked. See quest_template.id'"
Expand Down
2 changes: 2 additions & 0 deletions src/app/features/item/item-template/item-template.module.ts
Expand Up @@ -19,6 +19,7 @@ import { ItemEnchantmentSelectorModule } from '@keira-shared/modules/selectors/i
import { HolidaySelectorModule } from '@keira-shared/modules/selectors/holiday-selector/holiday-selector.module';
import { LanguageSelectorModule } from '@keira-shared/modules/selectors/language-selector/language-selector.module';
import { ItemLimitCategorySelectorModule } from '@keira-shared/modules/selectors/item-limit-category-selector/item-limit-category-selector.module';
import { QuestSelectorModule } from '@keira-shared/modules/selectors/quest-selector/quest-selector.module';

@NgModule({
declarations: [
Expand All @@ -41,6 +42,7 @@ import { ItemLimitCategorySelectorModule } from '@keira-shared/modules/selectors
HolidaySelectorModule,
LanguageSelectorModule,
ItemLimitCategorySelectorModule,
QuestSelectorModule,
],
exports: [
ItemTemplateComponent,
Expand Down
Expand Up @@ -35,6 +35,11 @@

<div class="form-group col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
<label class="control-label" for="PrevQuestID">PrevQuestID</label>
<keira-quest-selector-btn
[control]="editorService.form.controls.PrevQuestID"
[config]="{ name: 'PrevQuestID' }"
[modalClass]="'modal-lg'"
></keira-quest-selector-btn>
<i
class="fas fa-info-circle ml-1" [placement]="'auto'"
[tooltip]="'if > 0: previous quest id; if < 0 parent quest id'"
Expand All @@ -44,6 +49,11 @@

<div class="form-group col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
<label class="control-label" for="NextQuestID">NextQuestID</label>
<keira-quest-selector-btn
[control]="editorService.form.controls.NextQuestID"
[config]="{ name: 'NextQuestID' }"
[modalClass]="'modal-lg'"
></keira-quest-selector-btn>
<i
class="fas fa-info-circle ml-1" [placement]="'auto'"
[tooltip]="'Contains the next quest id, in case PrevQuestId of that other quest is not sufficient.'"
Expand Down
Expand Up @@ -230,5 +230,36 @@ describe('QuestTemplateAddon integration tests', () => {
);
});

it('changing a value via QuestSelector should correctly work', async () => {
const field = 'NextQuestID';
const mysqlQueryService = TestBed.inject(MysqlQueryService);
(mysqlQueryService.query as Spy).and.returnValue(of(
[{ ID: 123, LogTitle: 'Mock Quest' }]
));

page.clickElement(page.getSelectorBtn(field));
await page.whenReady();
page.expectModalDisplayed();

page.clickSearchBtn();

await fixture.whenStable();
page.clickRowOfDatatableInModal(0);
await page.whenReady();
page.clickModalSelect();
await page.whenReady();

page.expectDiffQueryToContain(
'UPDATE `quest_template_addon` SET `NextQuestID` = 123 WHERE (`ID` = 1234);'
);
page.expectFullQueryToContain(
'DELETE FROM `quest_template_addon` WHERE (`ID` = 1234);\n' +
'INSERT INTO `quest_template_addon` (`ID`, `MaxLevel`, `AllowableClasses`, `SourceSpellID`, `PrevQuestID`, `NextQuestID`, ' +
'`ExclusiveGroup`, `RewardMailTemplateID`, `RewardMailDelay`, `RequiredSkillID`, `RequiredSkillPoints`, `RequiredMinRepFaction`, ' +
'`RequiredMaxRepFaction`, `RequiredMinRepValue`, `RequiredMaxRepValue`, `ProvidedItemCount`, `SpecialFlags`) VALUES\n' +
'(1234, 1, 2, 3, 4, 123, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0);'
);
});

});
});
Expand Up @@ -14,6 +14,7 @@ import { QuestTemplateAddonService } from './quest-template-addon.service';
import { SpellSelectorModule } from '@keira-shared/modules/selectors/spell-selector/spell-selector.module';
import { FactionSelectorModule } from '@keira-shared/modules/selectors/faction-selector/faction-selector.module';
import { SkillSelectorModule } from '@keira-shared/modules/selectors/skill-selector/skill-selector.module';
import { QuestSelectorModule } from '@keira-shared/modules/selectors/quest-selector/quest-selector.module';

@NgModule({
declarations: [
Expand All @@ -31,6 +32,7 @@ import { SkillSelectorModule } from '@keira-shared/modules/selectors/skill-selec
SpellSelectorModule,
FactionSelectorModule,
SkillSelectorModule,
QuestSelectorModule,
],
exports: [
QuestTemplateAddonComponent,
Expand Down
19 changes: 19 additions & 0 deletions src/app/shared/modules/search/quest-search.service.spec.ts
@@ -0,0 +1,19 @@
import { TestBed } from '@angular/core/testing';
import { instance } from 'ts-mockito';

import { QuestSearchService } from './quest-search.service';
import { MockedSqliteQueryService } from '../../testing/mocks';
import { SqliteQueryService } from '@keira-shared/services/sqlite-query.service';

describe('QuestSearchService', () => {
beforeEach(() => TestBed.configureTestingModule({
providers: [
{ provide: SqliteQueryService, useValue: instance(MockedSqliteQueryService) },
]
}));

it('should be created', () => {
const service: QuestSearchService = TestBed.inject(QuestSearchService);
expect(service).toBeTruthy();
});
});
22 changes: 22 additions & 0 deletions src/app/shared/modules/search/quest-search.service.ts
@@ -0,0 +1,22 @@
import { Injectable } from '@angular/core';

import { SearchService } from './search.service';
import { MysqlQueryService } from '@keira-shared/services/mysql-query.service';
import {
QUEST_TEMPLATE_SEARCH_FIELDS,
QUEST_TEMPLATE_TABLE,
QuestTemplate,
} from '../../types/quest-template.type';

@Injectable({
providedIn: 'root'
})
export class QuestSearchService extends SearchService<QuestTemplate> {

/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690
constructor(
protected queryService: MysqlQueryService,
) {
super(queryService, QUEST_TEMPLATE_TABLE, QUEST_TEMPLATE_SEARCH_FIELDS);
}
}
@@ -0,0 +1,26 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { QuestSelectorBtnComponent } from './quest-selector-btn.component';
import { QuestSelectorModule } from './quest-selector.module';

describe('QuestSelectorBtnComponent', () => {
let component: QuestSelectorBtnComponent;
let fixture: ComponentFixture<QuestSelectorBtnComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ QuestSelectorModule ],
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(QuestSelectorBtnComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,23 @@
import { Component } from '@angular/core';
import { BsModalService } from 'ngx-bootstrap';

import { QuestSelectorModalComponent } from './quest-selector-modal.component';
import { BaseSelectorBtnComponent } from '../base-selector/base-selector-btn.component';

@Component({
selector: 'keira-quest-selector-btn',
templateUrl: '../base-selector/base-selector-btn.component.html',
styleUrls: ['../base-selector/base-selector-btn.component.scss']
})
export class QuestSelectorBtnComponent extends BaseSelectorBtnComponent {

/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690
constructor(
modalService: BsModalService,
) {
super(
QuestSelectorModalComponent,
modalService,
);
}
}
@@ -0,0 +1,57 @@
<div class="modal-body">

<p class="lead text-center mb-1">Quest selector</p>

<form [formGroup]="searchService.queryForm">
<div class="row">
<ng-container [formGroup]="searchService.fields">
<div class="form-group col-3">
<input [formControlName]="'ID'" type="number" class="form-control form-control-sm" id="ID" placeholder="ID">
</div>
<div class="form-group col-5">
<input [formControlName]="'LogTitle'" class="form-control form-control-sm" id="LogTitle" placeholder="Name">
</div>
</ng-container>
<div class="form-group col-2">
<input [formControlName]="'limit'" class="form-control form-control-sm" id="limit" placeholder="Unlimited">
</div>
<div class="col-2">
<button
id="search-btn"
class="btn btn-primary btn-sm"
[disabled]="searchService.queryForm.invalid"
(click)="searchService.onSearch()"
>Search</button>
</div>
</div>
<code [highlight]="searchService.query"></code>
</form>

<div *ngIf="searchService.rows">

<ngx-datatable
class="bootstrap table table-striped text-center datatable-select highlight-select"
[rows]="searchService.rows"
[headerHeight]="DTCFG.headerHeight"
[footerHeight]="DTCFG.footerHeight"
[columnMode]="DTCFG.columnMode"
[rowHeight]="DTCFG.rowHeight"
[limit]="DTCFG.limit"
[selectionType]="DTCFG.selectionType"
(select)='onSelect($event)'
>
<ngx-datatable-column name="ID" prop="ID" [minWidth]="100">
<ng-template let-row="row" ngx-datatable-cell-template>
{{ row.ID }}
</ng-template>
</ngx-datatable-column>
<ngx-datatable-column name="Quest Title" prop="LogTitle"></ngx-datatable-column>
</ngx-datatable>

</div>
</div>

<div class="modal-footer">
<button type="button" class="btn btn-danger" id="modal-cancel-btn" (click)="onCancel()">Cancel</button>
<button type="button" class="btn btn-success" id="modal-select-btn" (click)="onSave()">Select</button>
</div>
Empty file.
@@ -0,0 +1,39 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BsModalRef } from 'ngx-bootstrap';
import { instance } from 'ts-mockito';

import { QuestSelectorModalComponent } from './quest-selector-modal.component';
import { MysqlQueryService } from '../../../services/mysql-query.service';
import { MockedMysqlQueryService } from '@keira-testing/mocks';
import { QuestSearchService } from '../../search/quest-search.service';
import { QuestSelectorModule } from './quest-selector.module';

describe('QuestSelectorModalComponent', () => {
let component: QuestSelectorModalComponent;
let fixture: ComponentFixture<QuestSelectorModalComponent>;
let searchService: QuestSearchService;

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ QuestSelectorModule ],
providers: [
BsModalRef,
{ provide: MysqlQueryService, useValue: instance(MockedMysqlQueryService) },
],
})
.compileComponents();
}));

beforeEach(() => {
searchService = TestBed.inject(QuestSearchService);
searchService.query = '--mock query';

fixture = TestBed.createComponent(QuestSelectorModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
@@ -0,0 +1,22 @@
import { Component, } from '@angular/core';
import { BsModalRef } from 'ngx-bootstrap';

import { QuestSearchService } from '../../search/quest-search.service';
import { QUEST_TEMPLATE_ID } from '@keira-types/quest-template.type';
import { SearchSelectorModalComponent } from '../base-selector/search-selector-modal.component';

@Component({
selector: 'keira-quest-selector-modal',
templateUrl: './quest-selector-modal.component.html',
styleUrls: ['./quest-selector-modal.component.scss']
})
export class QuestSelectorModalComponent extends SearchSelectorModalComponent {

/* istanbul ignore next */ // because of: https://github.com/gotwarlost/istanbul/issues/690
constructor(
protected bsModalRef: BsModalRef,
public searchService: QuestSearchService,
) {
super(QUEST_TEMPLATE_ID, bsModalRef);
}
}
@@ -0,0 +1,31 @@
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';

import { QuestSelectorModalComponent } from './quest-selector-modal.component';
import { QuestSelectorBtnComponent } from './quest-selector-btn.component';
import { highlightOptions } from '@keira-config/highlight.config';
import { HighlightModule } from 'ngx-highlightjs';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { ModalModule } from 'ngx-bootstrap';

@NgModule({
entryComponents: [
QuestSelectorModalComponent,
],
declarations: [
QuestSelectorBtnComponent,
QuestSelectorModalComponent,
],
imports: [
BrowserModule,
ReactiveFormsModule,
NgxDatatableModule,
ModalModule.forRoot(),
HighlightModule.forRoot(highlightOptions),
],
exports: [
QuestSelectorBtnComponent,
],
})
export class QuestSelectorModule {}

0 comments on commit c8c3f37

Please sign in to comment.