(function() {
/**
* this backend connector is able to handle SEN catalogue content for a RW model configuration
* @augments Help4.widget.help.catalogues.SEN
*/
Help4.widget.help.catalogues.SEN2 = class extends Help4.widget.help.catalogues.SEN {
/**
* @override
* @param {Help4.typedef.SystemConfiguration} config - the system configuration
* @returns {Promise<Help4.widget.help.catalogues.SEN.CatalogueProjects|null>}
*/
static async load(config) {
const {wpb, sen, ext} = Help4.SERVICE_LAYER;
const {serviceLayer, rwModel, serviceUrl2} = config.help;
if (!serviceUrl2 || serviceLayer !== ext || rwModel !== wpb && rwModel !== sen) return null;
const {editor} = config.core;
const {serverBaseUrl, pubUrl, headUrl} = /** @type {Help4.widget.help.catalogues.SEN.CatalogueUrlConfig} */ this._getUrls(config, serviceUrl2);
const {SEN} = Help4.widget.companionCore;
if (editor) {
// editor: load PUB and HEAD
/** @type {Array<{url: string}>} */ const request = [pubUrl, headUrl].map(url => ({url}));
const [
/** @type {Array<?Help4.widget.companionCore.SEN.CatalogueResponse>} */ pub,
/** @type {Array<?Help4.widget.companionCore.SEN.CatalogueResponse>} */ head
] = await SEN.doMultifileRequest(config, {serverBaseUrl, request}) || [];
/** @type {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} */ const pubProjects = this._parse(pub, 'SEN2');
/** @type {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} */ const headProjects = this._parse(head, 'SEN2');
return {pub: pubProjects, head: headProjects};
} else {
// non-editor: load PUB only
/** @type {?Help4.widget.companionCore.SEN.CatalogueResponse} */ const pub = await SEN.doGetRequest(serverBaseUrl + pubUrl);
/** @type {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} */ const pubProjects = this._parse(pub, 'SEN2');
return {pub: pubProjects};
}
}
/**
* this function is to find the best match for RO - even if this selects a different project than the RW one
* for EXT in help mode two projects will be merged into one (UACP/SEN + SEN2)
* @param {string} screenId - current screen ID
* @param {Help4.widget.help.CatalogueSelection[]} selected - currently selected projects
* @param {Help4.widget.help.CatalogueProject[]} projects - all projects
* @param {Help4.typedef.SystemConfiguration} config - the system configuration
* @returns {?Help4.widget.help.CatalogueSelection}
*/
static getHelpSelection(screenId, selected, projects, config) {
// take the selected project from RO and search all possible extensions
// even in case they have not been selected due to language scores or other metrics
/** @type {Help4.widget.help.CatalogueSelection} */
const roSelected = selected.find(({catalogueType: ct}) => ct === 'UACP' || ct === 'SEN'); // RO source (UACP, SEN)
/** @type {Help4.widget.help.CatalogueProject[]} */
const extensions = projects.filter(({contextType: a, _catalogueType: b, screen: c}) => a === 'HELP' && b === 'SEN2' && c === screenId); // RW extensions (SEN2)
if (!roSelected || !extensions.length) return null; // not applicable
const {companionCore} = Help4.widget;
/** @type {Help4.widget.help.CatalogueProject} */ const roHelp = projects.find(({id}) => id === roSelected.id);
// roLangList && rwLangList should be of equal length, and it is fine if they have duplicate entries
// to find the equivalent RW language for RO, we need to find them by index and not by language code
// Ex 1: ro = [et-EE, fi-FI, en-US], rw = [et, fi, en-US]
// Ex 2: ro = [de-DE, de-DE, en-US], rw = [de-DE, de-CH, en-US]
/** @type {string[]} */ const roLangList = companionCore[roHelp._dataType].getLanguages(config, true);
/** @type {string[]} */ const rwLangList = companionCore.SEN.getLanguages(config, true);
// get all RW languages that are better than RO; find a better RW than RO
const roLangIndex = roLangList.indexOf(roHelp.language);
const betterLangList = rwLangList.slice(0, roLangIndex); // this will only have entries if RO not system language
/** @type {?Help4.widget.help.CatalogueProject} */
const betterRW = betterLangList.length &&
extensions.find(({language: l}) => betterLangList.indexOf(l) >= 0);
if (betterRW) {
// a better RW project has been found; ignore RO
const {_catalogueType: catalogueType, id} = betterRW;
return {catalogueType, id};
} else {
// get RW language that is the same as RO; find a matching RW
const matchingLangList = rwLangList.slice(0, roLangIndex + 1);
/** @type {?Help4.widget.help.CatalogueProject} */
let matchingRW = matchingLangList.length &&
extensions.find(({language: l}) => matchingLangList.indexOf(l) >= 0);
const {languageFallbackMode} = config.core;
if (!matchingRW && languageFallbackMode === 'mix') {
// RW content matching RO language not found
// select from fallback language
const rwFallbackLangList = rwLangList.slice(roLangIndex + 1, rwLangList.length);
for (const rwLang of rwFallbackLangList) {
matchingRW = extensions.find(({language}) => language === rwLang);
if (matchingRW) break;
}
}
if (matchingRW) {
// extension found; return joint result
const {_catalogueType: catalogueType, id} = roHelp;
const {_catalogueType: catalogueType2, id: id2} = matchingRW;
return {catalogueType, id, catalogueType2, id2};
}
}
// no better RW and no extension has been found (this means that RW has only low priority languages); return RO
return roSelected;
}
/**
* delivers a map with EXT information, e.g. {srcId: destId, ...}
* destId === <string>: this RW tour extends the one described by srcId
* destId === null: this RW tour must not be displayed; due to low-priority language
* @param {Help4.widget.help.CatalogueProject[]} projects
* @param {Help4.typedef.SystemConfiguration} config - the system configuration
* @returns {Object|null}
*/
static getTourList(projects, config) {
/** @type {Help4.widget.help.CatalogueProject[]} */ const roTours = projects.filter(({_catalogueType: ct}) => ct === 'UACP' || ct === 'SEN');
/** @type {Help4.widget.help.CatalogueProject[]} */ const rwTours = projects.filter(({_catalogueType: ct}) => ct === 'SEN2');
/** @type {Help4.widget.help.CatalogueProject} */ const roTour = roTours[0];
if (!roTour) return null; // not applicable
const {companionCore} = Help4.widget;
/** @type {string[]} */ const roLangList = companionCore[roTour._dataType].getLanguages(config, true);
/** @type {string[]} */ const rwLangList = companionCore.SEN.getLanguages(config, true);
// defines EXT targets for some tours
// RO.id -> RW.id: an RO tour is extended by an RW one
// RW.id -> null: an RW tour is extending an RO one but in the wrong language; to be ignored
const map = {};
/** @type {string[]} */ const accepted = [];
// find possible RW extensions of RO tours
for (const /** @type {Help4.widget.help.CatalogueProject} */ {language, loio, id} of roTours) {
// get all RW language that are better or same than RO
const matchingLangList = rwLangList.slice(0, roLangList.indexOf(language) + 1);
// check whether we find a matching RW for RO
/** @type {Help4.widget.help.CatalogueProject[]} */
const matchingRW = matchingLangList.length &&
rwTours.filter(({language: l}) => matchingLangList.indexOf(l) >= 0) || [];
// does RO have an extension in RW?
const {id: rwId} = /** @type {Help4.widget.help.CatalogueProject} */ matchingRW.find(({loio: l}) => l === loio) || {};
if (rwId) {
// roTour is extended by tour with rwId
map[id] = rwId;
accepted.push(rwId);
}
}
// find and remove RW extensions that have the wrong language
for (/** @type {Help4.widget.help.CatalogueProject} */ const rwTour of rwTours) {
if (accepted.indexOf(rwTour.id) >= 0) continue; // ignore RW tours that have been accepted for EXT already
if (roTours.find(({loio}) => loio === rwTour.loio)) {
// RW tour is EXT for RO but obviously wrong language
// otherwise would have been selected for EXT in loop above
map[rwTour.id] = null;
}
}
return accepted.length ? map : null;
}
}
})();