@studyportals/fawkes 8.2.4-2 → 8.2.4-21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/common/IPresenter.d.ts +2 -1
- package/dist/src/enums/FilterCombinations.d.ts +2 -1
- package/dist/src/enums/FilterCombinations.js +2 -1
- package/dist/src/organisations/SearchIndexabilityManager.js +3 -2
- package/dist/src/organisations/policies/index.d.ts +2 -1
- package/dist/src/organisations/policies/index.js +2 -1
- package/dist/src/organisations/policies/our-picks/CountryAreaCity.d.ts +13 -0
- package/dist/src/organisations/policies/our-picks/CountryAreaCity.js +44 -0
- package/dist/src/organisations/policies/our-picks/CountryCity.d.ts +13 -0
- package/dist/src/organisations/policies/our-picks/CountryCity.js +38 -0
- package/dist/src/organisations/policies/ranked/RankedCountryAreaCity.d.ts +11 -0
- package/dist/src/organisations/policies/ranked/RankedCountryAreaCity.js +42 -0
- package/dist/src/organisations/policies/ranked/RankedCountryCity.d.ts +11 -0
- package/dist/src/organisations/policies/ranked/RankedCountryCity.js +36 -0
- package/dist/src/organisations/rules/OnlyFullLocationFiltersSelectedRule.js +1 -2
- package/dist/src/presenters/CityPresenter.d.ts +3 -2
- package/dist/src/presenters/CityPresenter.js +24 -27
- package/dist/src/presenters/fragments/ICityFragment.d.ts +1 -1
- package/dist/src/sitemap-generator/ICity.d.ts +7 -0
- package/dist/src/sitemap-generator/ICity.js +1 -0
- package/dist/src/sitemap-generator/ISearchApiClient.d.ts +2 -2
- package/dist/src/sitemap-generator/OrganisationsSitemapUrlGeneratorManager.js +6 -2
- package/package.json +1 -1
|
@@ -2,5 +2,6 @@ import { IFragment } from '../presenters/fragments/IFragment';
|
|
|
2
2
|
import { FilterKey } from '@studyportals/search-filters/server-side';
|
|
3
3
|
export interface IPresenter {
|
|
4
4
|
readonly filterKey: FilterKey;
|
|
5
|
-
getFragments(): IFragment[]
|
|
5
|
+
getFragments(): IFragment[];
|
|
6
|
+
getFragmentsAsync?(): Promise<IFragment[]>;
|
|
6
7
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
export declare enum FilterCombinations {
|
|
2
|
-
CITY = "city",
|
|
3
2
|
AREA = "area",
|
|
4
3
|
AREA_ATTENDANCE = "areaAttendance",
|
|
5
4
|
AREA_DISCIPLINE = "areaDiscipline",
|
|
6
5
|
COUNTRY = "country",
|
|
6
|
+
COUNTRY_CITY = "countryCity",
|
|
7
|
+
COUNTRY_AREA_CITY = "countryAreaCity",
|
|
7
8
|
DEGREE = "degree",
|
|
8
9
|
DURATION = "duration",
|
|
9
10
|
FORMAT = "format",
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export var FilterCombinations;
|
|
2
2
|
(function (FilterCombinations) {
|
|
3
|
-
FilterCombinations["CITY"] = "city";
|
|
4
3
|
FilterCombinations["AREA"] = "area";
|
|
5
4
|
FilterCombinations["AREA_ATTENDANCE"] = "areaAttendance";
|
|
6
5
|
FilterCombinations["AREA_DISCIPLINE"] = "areaDiscipline";
|
|
7
6
|
FilterCombinations["COUNTRY"] = "country";
|
|
7
|
+
FilterCombinations["COUNTRY_CITY"] = "countryCity";
|
|
8
|
+
FilterCombinations["COUNTRY_AREA_CITY"] = "countryAreaCity";
|
|
8
9
|
FilterCombinations["DEGREE"] = "degree";
|
|
9
10
|
FilterCombinations["DURATION"] = "duration";
|
|
10
11
|
FilterCombinations["FORMAT"] = "format";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DependencyTypes } from '../enums/DependencyTypes';
|
|
2
|
-
import {
|
|
2
|
+
import { Area, AreaAttendance, Attendance, Continent, Country, CountryAttendance, Unfiltered, RankedArea, RankedAreaDiscipline, RankedAttendance, RankedAttendanceDiscipline, RankedContinent, RankedContinentAttendance, RankedCountry, RankedCountryAttendance, RankedCountryDiscipline, RankedDiscipline, RankedUnfiltered, CountryCity, CountryAreaCity } from '../organisations/policies';
|
|
3
3
|
export class SearchIndexabilityManager {
|
|
4
4
|
policies;
|
|
5
5
|
constructor(portalType, seoInfoBase, filterState, sortingState, applicationState) {
|
|
@@ -12,12 +12,13 @@ export class SearchIndexabilityManager {
|
|
|
12
12
|
portalType
|
|
13
13
|
};
|
|
14
14
|
this.policies = [
|
|
15
|
-
new City(dependencies),
|
|
16
15
|
new Area(dependencies),
|
|
17
16
|
new AreaAttendance(dependencies),
|
|
18
17
|
new Attendance(dependencies),
|
|
19
18
|
new Continent(dependencies),
|
|
20
19
|
new Country(dependencies),
|
|
20
|
+
new CountryCity(dependencies),
|
|
21
|
+
new CountryAreaCity(dependencies),
|
|
21
22
|
new CountryAttendance(dependencies),
|
|
22
23
|
new Unfiltered(dependencies),
|
|
23
24
|
new RankedArea(dependencies),
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export * from './our-picks/City';
|
|
2
1
|
export * from './our-picks/Area';
|
|
3
2
|
export * from './our-picks/AreaAttendance';
|
|
4
3
|
export * from './our-picks/Attendance';
|
|
5
4
|
export * from './our-picks/Continent';
|
|
6
5
|
export * from './our-picks/Country';
|
|
6
|
+
export * from './our-picks/CountryCity';
|
|
7
|
+
export * from './our-picks/CountryAreaCity';
|
|
7
8
|
export * from './our-picks/CountryAttendance';
|
|
8
9
|
export * from './our-picks/Unfiltered';
|
|
9
10
|
export * from './ranked/RankedArea';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export * from './our-picks/City';
|
|
2
1
|
export * from './our-picks/Area';
|
|
3
2
|
export * from './our-picks/AreaAttendance';
|
|
4
3
|
export * from './our-picks/Attendance';
|
|
5
4
|
export * from './our-picks/Continent';
|
|
6
5
|
export * from './our-picks/Country';
|
|
6
|
+
export * from './our-picks/CountryCity';
|
|
7
|
+
export * from './our-picks/CountryAreaCity';
|
|
7
8
|
export * from './our-picks/CountryAttendance';
|
|
8
9
|
export * from './our-picks/Unfiltered';
|
|
9
10
|
export * from './ranked/RankedArea';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
2
|
+
import { SortingOptions } from '../../../enums/SortingOptions';
|
|
3
|
+
import { OrganisationsSeoIndexabilityPolicy } from '../../../organisations/policies/OrganisationsSeoIndexabilityPolicy';
|
|
4
|
+
import { SingleValueSelectedForFilterRule } from '../../../common/rules/SingleValueSelectedForFilterRule';
|
|
5
|
+
import { OnlyFiltersSelectedRule } from '../../../common/rules/OnlyFiltersSelectedRule';
|
|
6
|
+
export declare class CountryAreaCity extends OrganisationsSeoIndexabilityPolicy {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly description: string;
|
|
9
|
+
protected readonly sortingOption = SortingOptions.OUR_PICKS;
|
|
10
|
+
protected readonly baseRules: (SingleValueSelectedForFilterRule | OnlyFiltersSelectedRule)[];
|
|
11
|
+
protected generateUrls(): Promise<string[]>;
|
|
12
|
+
get filterCombination(): FilterCombinations;
|
|
13
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
2
|
+
import { FilterKey } from '@studyportals/search-filters/server-side';
|
|
3
|
+
import { SortingOptions } from '../../../enums/SortingOptions';
|
|
4
|
+
import { OrganisationsSeoIndexabilityPolicy } from '../../../organisations/policies/OrganisationsSeoIndexabilityPolicy';
|
|
5
|
+
import { SingleValueSelectedForFilterRule } from '../../../common/rules/SingleValueSelectedForFilterRule';
|
|
6
|
+
import { OnlyFiltersSelectedRule } from '../../../common/rules/OnlyFiltersSelectedRule';
|
|
7
|
+
import { CityPresenter } from '../../../presenters/CityPresenter';
|
|
8
|
+
export class CountryAreaCity extends OrganisationsSeoIndexabilityPolicy {
|
|
9
|
+
name = 'Country Area City Policy';
|
|
10
|
+
description = 'Controls indexing of pages filtered by geographic cities and areas, ensuring only SEO-valuable regional content with sufficient search volume is indexed.';
|
|
11
|
+
sortingOption = SortingOptions.OUR_PICKS;
|
|
12
|
+
baseRules = [
|
|
13
|
+
new SingleValueSelectedForFilterRule(FilterKey.CITY),
|
|
14
|
+
new SingleValueSelectedForFilterRule(FilterKey.COUNTRY),
|
|
15
|
+
new SingleValueSelectedForFilterRule(FilterKey.AREA),
|
|
16
|
+
new OnlyFiltersSelectedRule([FilterKey.CITY, FilterKey.COUNTRY, FilterKey.AREA])
|
|
17
|
+
];
|
|
18
|
+
async generateUrls() {
|
|
19
|
+
const cityFragments = await CityPresenter
|
|
20
|
+
.getInstance(this.dependencies.searchApiClient)
|
|
21
|
+
.getFragmentsAsync();
|
|
22
|
+
const paths = [];
|
|
23
|
+
const filteredFragmentsForCountryAreaCity = cityFragments.filter(city => city.areaId !== null && city.areaId !== undefined);
|
|
24
|
+
for (const city of filteredFragmentsForCountryAreaCity) {
|
|
25
|
+
const areaId = city.areaId?.toString() || '';
|
|
26
|
+
if (areaId === '') {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const filterKeyValues = new Map([
|
|
30
|
+
[FilterKey.CITY, [city.id]],
|
|
31
|
+
[FilterKey.AREA, [areaId]],
|
|
32
|
+
[FilterKey.COUNTRY, [city.countryId]]
|
|
33
|
+
]);
|
|
34
|
+
const result = await this.checkRulesForSitemap(filterKeyValues);
|
|
35
|
+
if (result) {
|
|
36
|
+
paths.push(this.getPathWithSortingOption(city.path));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return paths;
|
|
40
|
+
}
|
|
41
|
+
get filterCombination() {
|
|
42
|
+
return FilterCombinations.COUNTRY_AREA_CITY;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
2
|
+
import { SortingOptions } from '../../../enums/SortingOptions';
|
|
3
|
+
import { OrganisationsSeoIndexabilityPolicy } from '../../../organisations/policies/OrganisationsSeoIndexabilityPolicy';
|
|
4
|
+
import { SingleValueSelectedForFilterRule } from '../../../common/rules/SingleValueSelectedForFilterRule';
|
|
5
|
+
import { OnlyFiltersSelectedRule } from '../../../common/rules/OnlyFiltersSelectedRule';
|
|
6
|
+
export declare class CountryCity extends OrganisationsSeoIndexabilityPolicy {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly description: string;
|
|
9
|
+
protected readonly sortingOption = SortingOptions.OUR_PICKS;
|
|
10
|
+
protected readonly baseRules: (SingleValueSelectedForFilterRule | OnlyFiltersSelectedRule)[];
|
|
11
|
+
protected generateUrls(): Promise<string[]>;
|
|
12
|
+
get filterCombination(): FilterCombinations;
|
|
13
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
2
|
+
import { FilterKey } from '@studyportals/search-filters/server-side';
|
|
3
|
+
import { SortingOptions } from '../../../enums/SortingOptions';
|
|
4
|
+
import { OrganisationsSeoIndexabilityPolicy } from '../../../organisations/policies/OrganisationsSeoIndexabilityPolicy';
|
|
5
|
+
import { CityPresenter } from '../../../presenters/CityPresenter';
|
|
6
|
+
import { SingleValueSelectedForFilterRule } from '../../../common/rules/SingleValueSelectedForFilterRule';
|
|
7
|
+
import { OnlyFiltersSelectedRule } from '../../../common/rules/OnlyFiltersSelectedRule';
|
|
8
|
+
export class CountryCity extends OrganisationsSeoIndexabilityPolicy {
|
|
9
|
+
name = 'Country City Policy';
|
|
10
|
+
description = 'Controls indexing of pages filtered by geographic cities, ensuring only SEO-valuable regional content with sufficient search volume is indexed.';
|
|
11
|
+
sortingOption = SortingOptions.OUR_PICKS;
|
|
12
|
+
baseRules = [
|
|
13
|
+
new SingleValueSelectedForFilterRule(FilterKey.CITY),
|
|
14
|
+
new SingleValueSelectedForFilterRule(FilterKey.COUNTRY),
|
|
15
|
+
new OnlyFiltersSelectedRule([FilterKey.CITY, FilterKey.COUNTRY])
|
|
16
|
+
];
|
|
17
|
+
async generateUrls() {
|
|
18
|
+
const cityFragments = await CityPresenter
|
|
19
|
+
.getInstance(this.dependencies.searchApiClient)
|
|
20
|
+
.getFragmentsAsync();
|
|
21
|
+
const paths = [];
|
|
22
|
+
const filteredFragmentsForCountryCity = cityFragments.filter(city => city.areaId === null || city.areaId === undefined);
|
|
23
|
+
for (const city of filteredFragmentsForCountryCity) {
|
|
24
|
+
const filterKeyValues = new Map([
|
|
25
|
+
[FilterKey.CITY, [city.id]],
|
|
26
|
+
[FilterKey.COUNTRY, [city.countryId]]
|
|
27
|
+
]);
|
|
28
|
+
const result = await this.checkRulesForSitemap(filterKeyValues);
|
|
29
|
+
if (result) {
|
|
30
|
+
paths.push(this.getPathWithSortingOption(city.path));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return paths;
|
|
34
|
+
}
|
|
35
|
+
get filterCombination() {
|
|
36
|
+
return FilterCombinations.COUNTRY_CITY;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OnlyFiltersSelectedRule } from "../../../common/rules/OnlyFiltersSelectedRule";
|
|
2
|
+
import { SingleValueSelectedForFilterRule } from "../../../common/rules/SingleValueSelectedForFilterRule";
|
|
3
|
+
import { RankedOrganisationsSeoIndexabilityPolicy } from "../RankedOrganisationsSeoIndexabilityPolicy";
|
|
4
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
5
|
+
export declare class RankedCountryAreaCity extends RankedOrganisationsSeoIndexabilityPolicy {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly description: string;
|
|
8
|
+
protected readonly baseRules: (SingleValueSelectedForFilterRule | OnlyFiltersSelectedRule)[];
|
|
9
|
+
protected generateUrls(): Promise<string[]>;
|
|
10
|
+
get filterCombination(): FilterCombinations;
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { OnlyFiltersSelectedRule } from "../../../common/rules/OnlyFiltersSelectedRule";
|
|
2
|
+
import { SingleValueSelectedForFilterRule } from "../../../common/rules/SingleValueSelectedForFilterRule";
|
|
3
|
+
import { FilterKey } from "@studyportals/search-filters/server-side";
|
|
4
|
+
import { RankedOrganisationsSeoIndexabilityPolicy } from "../RankedOrganisationsSeoIndexabilityPolicy";
|
|
5
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
6
|
+
import { CityPresenter } from "../../../presenters/CityPresenter";
|
|
7
|
+
export class RankedCountryAreaCity extends RankedOrganisationsSeoIndexabilityPolicy {
|
|
8
|
+
name = 'Ranked Country Area City Policy';
|
|
9
|
+
description = 'Manages indexability of ranking-sorted country and area-specific city pages, applying rules to prioritize regions where quality-based sorting adds search value.';
|
|
10
|
+
baseRules = [
|
|
11
|
+
new SingleValueSelectedForFilterRule(FilterKey.CITY),
|
|
12
|
+
new SingleValueSelectedForFilterRule(FilterKey.COUNTRY),
|
|
13
|
+
new OnlyFiltersSelectedRule([FilterKey.CITY, FilterKey.COUNTRY])
|
|
14
|
+
];
|
|
15
|
+
async generateUrls() {
|
|
16
|
+
const cityFragments = await CityPresenter
|
|
17
|
+
.getInstance(this.dependencies.searchApiClient)
|
|
18
|
+
.getFragmentsAsync();
|
|
19
|
+
const paths = [];
|
|
20
|
+
console.warn(`Total city fragments fetched: ${cityFragments.length}`);
|
|
21
|
+
const filteredFragmentsForCountryAreaCity = cityFragments.filter(city => city.areaId !== null && city.areaId !== undefined);
|
|
22
|
+
for (const city of filteredFragmentsForCountryAreaCity) {
|
|
23
|
+
const areaId = city.areaId?.toString() || '';
|
|
24
|
+
if (areaId === '') {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const filterKeyValues = new Map([
|
|
28
|
+
[FilterKey.CITY, [city.id]],
|
|
29
|
+
[FilterKey.AREA, [areaId]],
|
|
30
|
+
[FilterKey.COUNTRY, [city.countryId]]
|
|
31
|
+
]);
|
|
32
|
+
const result = await this.checkRulesForSitemap(filterKeyValues);
|
|
33
|
+
if (result) {
|
|
34
|
+
paths.push(this.getPathWithSortingOption(city.path));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return paths;
|
|
38
|
+
}
|
|
39
|
+
get filterCombination() {
|
|
40
|
+
return FilterCombinations.RANKED_COUNTRY_AREA_CITY;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OnlyFiltersSelectedRule } from "../../../common/rules/OnlyFiltersSelectedRule";
|
|
2
|
+
import { SingleValueSelectedForFilterRule } from "../../../common/rules/SingleValueSelectedForFilterRule";
|
|
3
|
+
import { RankedOrganisationsSeoIndexabilityPolicy } from "../RankedOrganisationsSeoIndexabilityPolicy";
|
|
4
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
5
|
+
export declare class RankedCountryCity extends RankedOrganisationsSeoIndexabilityPolicy {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly description: string;
|
|
8
|
+
protected readonly baseRules: (SingleValueSelectedForFilterRule | OnlyFiltersSelectedRule)[];
|
|
9
|
+
protected generateUrls(): Promise<string[]>;
|
|
10
|
+
get filterCombination(): FilterCombinations;
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { OnlyFiltersSelectedRule } from "../../../common/rules/OnlyFiltersSelectedRule";
|
|
2
|
+
import { SingleValueSelectedForFilterRule } from "../../../common/rules/SingleValueSelectedForFilterRule";
|
|
3
|
+
import { FilterKey } from "@studyportals/search-filters/server-side";
|
|
4
|
+
import { RankedOrganisationsSeoIndexabilityPolicy } from "../RankedOrganisationsSeoIndexabilityPolicy";
|
|
5
|
+
import { FilterCombinations } from '../../../enums/FilterCombinations';
|
|
6
|
+
import { CityPresenter } from "../../../presenters/CityPresenter";
|
|
7
|
+
export class RankedCountryCity extends RankedOrganisationsSeoIndexabilityPolicy {
|
|
8
|
+
name = 'Ranked Country City Policy';
|
|
9
|
+
description = 'Manages indexability of ranking-sorted country and city-specific pages, applying rules to prioritize regions where quality-based sorting adds search value.';
|
|
10
|
+
baseRules = [
|
|
11
|
+
new SingleValueSelectedForFilterRule(FilterKey.CITY),
|
|
12
|
+
new SingleValueSelectedForFilterRule(FilterKey.COUNTRY),
|
|
13
|
+
new OnlyFiltersSelectedRule([FilterKey.CITY, FilterKey.COUNTRY])
|
|
14
|
+
];
|
|
15
|
+
async generateUrls() {
|
|
16
|
+
const cityFragments = await CityPresenter
|
|
17
|
+
.getInstance(this.dependencies.searchApiClient)
|
|
18
|
+
.getFragmentsAsync();
|
|
19
|
+
const paths = [];
|
|
20
|
+
const filteredFragmentsForCountryCity = cityFragments.filter(city => city.areaId === null || city.areaId === undefined);
|
|
21
|
+
for (const city of filteredFragmentsForCountryCity) {
|
|
22
|
+
const filterKeyValues = new Map([
|
|
23
|
+
[FilterKey.CITY, [city.id]],
|
|
24
|
+
[FilterKey.COUNTRY, [city.countryId]]
|
|
25
|
+
]);
|
|
26
|
+
const result = await this.checkRulesForSitemap(filterKeyValues);
|
|
27
|
+
if (result) {
|
|
28
|
+
paths.push(this.getPathWithSortingOption(city.path));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return paths;
|
|
32
|
+
}
|
|
33
|
+
get filterCombination() {
|
|
34
|
+
return FilterCombinations.RANKED_COUNTRY_CITY;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -8,8 +8,7 @@ export class OnlyFullLocationFiltersSelectedRule {
|
|
|
8
8
|
return await this.isEligible(dependencies);
|
|
9
9
|
}
|
|
10
10
|
forSitemapGenerator() {
|
|
11
|
-
|
|
12
|
-
return Promise.resolve(false);
|
|
11
|
+
return Promise.resolve(true);
|
|
13
12
|
}
|
|
14
13
|
getDescription() {
|
|
15
14
|
return `Only city, country and area (if US, UK or AU) filters are selected`;
|
|
@@ -5,10 +5,11 @@ export declare class CityPresenter implements IPresenter {
|
|
|
5
5
|
readonly filterKey: FilterKey;
|
|
6
6
|
private searchApiClient;
|
|
7
7
|
private static instance;
|
|
8
|
-
private resultSize;
|
|
9
8
|
private constructor();
|
|
10
9
|
private fragmentsPromise;
|
|
11
10
|
static getInstance(searchApiClient: ISearchApiClient): CityPresenter;
|
|
12
|
-
getFragments():
|
|
11
|
+
getFragments(): ICityFragment[];
|
|
12
|
+
getFragmentsAsync(): Promise<ICityFragment[]>;
|
|
13
13
|
private fetchCities;
|
|
14
|
+
private processCity;
|
|
14
15
|
}
|
|
@@ -6,7 +6,6 @@ export class CityPresenter {
|
|
|
6
6
|
filterKey = FilterKey.CITY;
|
|
7
7
|
searchApiClient;
|
|
8
8
|
static instance;
|
|
9
|
-
resultSize = 600;
|
|
10
9
|
constructor(searchApiClient) {
|
|
11
10
|
this.searchApiClient = searchApiClient;
|
|
12
11
|
}
|
|
@@ -17,7 +16,10 @@ export class CityPresenter {
|
|
|
17
16
|
}
|
|
18
17
|
return CityPresenter.instance;
|
|
19
18
|
}
|
|
20
|
-
|
|
19
|
+
getFragments() {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
async getFragmentsAsync() {
|
|
21
23
|
if (!this.fragmentsPromise) {
|
|
22
24
|
this.fragmentsPromise = this.fetchCities();
|
|
23
25
|
}
|
|
@@ -25,31 +27,12 @@ export class CityPresenter {
|
|
|
25
27
|
}
|
|
26
28
|
async fetchCities() {
|
|
27
29
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
cityPath += countryPath;
|
|
35
|
-
}
|
|
36
|
-
if (!city.areaId || city.areaId !== null) {
|
|
37
|
-
const area = areaGetPath(city.areaId?.toString() || '');
|
|
38
|
-
if (area && area !== '') {
|
|
39
|
-
cityPath += `/${area}`;
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
cityPath += countryPath;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
cityPath += `/${city.virtualPath}`;
|
|
46
|
-
return {
|
|
47
|
-
id: city.id.toString(),
|
|
48
|
-
path: cityPath,
|
|
49
|
-
areaId: city.areaId?.toString(),
|
|
50
|
-
countryId: country ? country.id.toString() : '',
|
|
51
|
-
};
|
|
52
|
-
});
|
|
30
|
+
if (!this.searchApiClient.getCities) {
|
|
31
|
+
console.error('searchApiClient.getCities is not found');
|
|
32
|
+
throw new Error('searchApiClient.getCities is not found');
|
|
33
|
+
}
|
|
34
|
+
const cities = await this.searchApiClient.getCities();
|
|
35
|
+
const cityFragments = cities.map(city => this.processCity(city));
|
|
53
36
|
return cityFragments;
|
|
54
37
|
}
|
|
55
38
|
catch (error) {
|
|
@@ -57,4 +40,18 @@ export class CityPresenter {
|
|
|
57
40
|
throw error;
|
|
58
41
|
}
|
|
59
42
|
}
|
|
43
|
+
processCity(city) {
|
|
44
|
+
const country = countriesExtendedAll.find(item => item.iso?.toLowerCase() === city.countryIsoCode?.toLowerCase());
|
|
45
|
+
const countryPath = countryGetIsoCodePath(country?.iso || '');
|
|
46
|
+
const areaPath = city.areaId != null ? areaGetPath(city.areaId.toString()) : '';
|
|
47
|
+
const useAreaPath = areaPath && areaPath.trim() !== '';
|
|
48
|
+
// AreaPath do also includes country, for that reason, we do not need to add countryPath if area exists
|
|
49
|
+
const cityPath = `${useAreaPath ? areaPath : countryPath}/${city.virtualPath}`;
|
|
50
|
+
return {
|
|
51
|
+
id: city.id.toString(),
|
|
52
|
+
path: cityPath,
|
|
53
|
+
areaId: useAreaPath ? city.areaId?.toString() : null,
|
|
54
|
+
countryId: country ? country.id.toString() : '',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
60
57
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,13 +2,13 @@ import { FilterKeyValuesMap } from '../common/FilterKeyValuesMap';
|
|
|
2
2
|
export interface ISearchApiClient {
|
|
3
3
|
getOrganisationIds(): Promise<number[]>;
|
|
4
4
|
getCityIds?(): Promise<number[]>;
|
|
5
|
-
getCities(): Promise<{
|
|
5
|
+
getCities?(): Promise<{
|
|
6
6
|
id: number;
|
|
7
7
|
name: string;
|
|
8
8
|
virtualPath: string;
|
|
9
9
|
areaId: number | null;
|
|
10
10
|
countryIsoCode: string;
|
|
11
11
|
}[]>;
|
|
12
|
-
getProgrammeCount(filterKeyValues: FilterKeyValuesMap): Promise<number>;
|
|
12
|
+
getProgrammeCount?(filterKeyValues: FilterKeyValuesMap): Promise<number>;
|
|
13
13
|
getCount(filterKeyValues: FilterKeyValuesMap): Promise<number>;
|
|
14
14
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { DependencyTypes } from '../enums/DependencyTypes';
|
|
2
2
|
import { BaseSitemapUrlGeneratorManager } from './BaseSitemapUrlGeneratorManager';
|
|
3
|
-
import {
|
|
3
|
+
import { Area, AreaAttendance, Attendance, Continent, Country, CountryCity, CountryAttendance, RankedArea, RankedAreaDiscipline, RankedAttendance, RankedAttendanceDiscipline, RankedContinent, RankedContinentAttendance, RankedCountry, RankedCountryAttendance, RankedCountryDiscipline, RankedDiscipline, RankedUnfiltered, Unfiltered } from '../organisations/policies';
|
|
4
4
|
import { AreaPresenter } from '../presenters/AreaPresenter';
|
|
5
5
|
import { AttendancePresenter } from '../presenters/AttendancePresenter';
|
|
6
6
|
import { ContinentPresenter } from '../presenters/ContinentPresenter';
|
|
7
7
|
import { CountryPresenter } from '../presenters/CountryPresenter';
|
|
8
8
|
import { DisciplinePresenter } from '../presenters/DisciplinePresenter';
|
|
9
9
|
import { FilterKey } from '@studyportals/search-filters/server-side';
|
|
10
|
+
import { CountryAreaCity } from '../organisations/policies/our-picks/CountryAreaCity';
|
|
11
|
+
import { CityPresenter } from '../presenters/CityPresenter';
|
|
10
12
|
export class OrganisationsSitemapUrlGeneratorManager extends BaseSitemapUrlGeneratorManager {
|
|
11
13
|
portalType;
|
|
12
14
|
policies;
|
|
@@ -22,7 +24,8 @@ export class OrganisationsSitemapUrlGeneratorManager extends BaseSitemapUrlGener
|
|
|
22
24
|
rankingApiClient
|
|
23
25
|
};
|
|
24
26
|
this.policies = [
|
|
25
|
-
new
|
|
27
|
+
new CountryCity(dependencies),
|
|
28
|
+
new CountryAreaCity(dependencies),
|
|
26
29
|
new Area(dependencies),
|
|
27
30
|
new AreaAttendance(dependencies),
|
|
28
31
|
new Attendance(dependencies),
|
|
@@ -47,6 +50,7 @@ export class OrganisationsSitemapUrlGeneratorManager extends BaseSitemapUrlGener
|
|
|
47
50
|
this.presenters.set(FilterKey.CONTINENT, ContinentPresenter.getInstance());
|
|
48
51
|
this.presenters.set(FilterKey.COUNTRY, CountryPresenter.getInstance());
|
|
49
52
|
this.presenters.set(FilterKey.DISCIPLINES, DisciplinePresenter.getInstance());
|
|
53
|
+
this.presenters.set(FilterKey.CITY, CityPresenter.getInstance(searchApiClient));
|
|
50
54
|
this.setFilterKeyValueCounts();
|
|
51
55
|
}
|
|
52
56
|
}
|