(function() {
/**
* @typedef {Object} Help4.widget.help.catalogues.SEN.CatalogueUrlConfig
* @property {string} serverBaseUrl - base URL of the content server
* @property {string} pubUrl - URL extension to public end-user content
* @property {string} headUrl - URL extension to non-public author only content
*/
/**
* @typedef {Object} Help4.widget.help.catalogues.SEN.CatalogueProject
* @property {string} [alias] - alternative project name; internally added
* @property {string} appUrl - screen ID
* @property {string} [clone_src] - clone source of project
* @property {string} [cloneSrc] - reduced clone source of project; internally added
* @property {string|Array<*>} conditions - possible conditions; stringified JSON or array
* @property {Help4.widget.help.ContextTypes} contextType - context type
* @property {boolean} hidden - whether project is hidden for end-users
* @property {string} id - project ID
* @property {string} locale - project language
* @property {string} loio - project LOIO (LOgical Info Object)
* @property {number|string} [maxversion] - highest version of project
* @property {string} modification_time - time of last modification
* @property {string} product - context information
* @property {Help4.widget.help.PUBLISHED_STATUS} [published] - project published information
* @property {string} system - context information
* @property {string} title - title of the project
* @property {string} version - context information
* @property {number} [wt] - write token information
* @property {string} [wt_location] - write token information
* @property {string} [wt_owner] - write token information
* @property {Help4.widget.help.CatalogueTypes} [_catalogueType] - SEN, SEN2, UACP, ...; internally added
* @property {Help4.widget.help.DataTypes} [_dataType] - SEN, UACP, ...; internally added
*/
/**
* @typedef {Object} Help4.widget.help.catalogues.SEN.CatalogueProjects
* @property {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} pub - public catalogue projects for end-users
* @property {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} [head] - non-public catalogue projects for authors
*/
/**
* this backend connector is able to handle SEN catalogue content for a RO model configuration
* - in case of SEN config: will download published and head data
* - in case of EXT config: will only download published data
*/
Help4.widget.help.catalogues.SEN = class {
/** @returns {Help4.widget.help.DataTypes} */
static getDataType() {
return 'SEN';
}
/**
* @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 {roModel, serviceUrl} = config.help;
if (!serviceUrl || roModel !== wpb && roModel !== sen) return null;
const {help: {serviceLayer}, core: {editor}} = config;
const {serverBaseUrl, pubUrl, headUrl} = /** @type {Help4.widget.help.catalogues.SEN.CatalogueUrlConfig} */ this._getUrls(config, serviceUrl);
// important: in case of EXT - always load and use published data for RO source!
const {SEN} = Help4.widget.companionCore;
if (editor && serviceLayer !== ext) {
// 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);
/** @type {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null} */ const headProjects = this._parse(head);
return {pub: pubProjects, head: headProjects};
} else {
// non-editor or EXT: 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);
return {pub: pubProjects};
}
}
/**
* @param {?Help4.widget.companionCore.SEN.CatalogueResponse} serverResponse - the server response
* @param {Help4.widget.help.CatalogueTypes} [catalogueType = 'SEN']
* @returns {Help4.widget.help.catalogues.SEN.CatalogueProject[]|null}
* @protected
*/
static _parse(serverResponse, catalogueType = 'SEN') {
/**
* @param {Help4.widget.help.catalogues.SEN.CatalogueProject} project - catalogue project data
* @returns {Help4.widget.help.catalogues.SEN.CatalogueProject}
*/
const normalize = project => {
const {clone_src, contextType, id, maxversion, published} = project;
project._catalogueType = catalogueType;
project._dataType = 'SEN';
project.loio ||= id;
project.alias = project.loio; // XRAY-3406
if (contextType === 'TOUR' && clone_src) project.cloneSrc = clone_src.split('!')[1];
const {PUBLISHED_STATUS} = Help4.widget.help;
const pub = Number(published);
const max = Number(maxversion);
project.published = isNaN(max)
? PUBLISHED_STATUS.invalid
: isNaN(pub) ? PUBLISHED_STATUS.new : (pub === max ? PUBLISHED_STATUS.published : PUBLISHED_STATUS.updated);
return setDefaults(project);
}
/**
* @param {Help4.widget.help.catalogues.SEN.CatalogueProject} project - project data
* @returns {Help4.widget.help.catalogues.SEN.CatalogueProject}
*/
const setDefaults = project => {
for (const [key, {d, f, t, wpb}] of Object.entries(Help4.PROJECT_DEFAULTS)) {
const value = project[wpb || key];
if (value === undefined) {
project[key] = f;
continue;
}
if (t === 'json') {
try {
project[key] = Help4.JSON.parse(value);
} catch (e) {
project[key] = f;
}
} else {
project[key] = value;
}
}
return project;
}
const {status, response} = serverResponse || {};
return !status && Help4.isArray(response) && response.length
? response.map(catalogueProject => normalize(catalogueProject))
: null;
}
/**
* @param {Help4.typedef.SystemConfiguration} config - the system configuration
* @param {string} serviceUrl - the server base URL
* @returns {Help4.widget.help.catalogues.SEN.CatalogueUrlConfig}
* @protected
*/
static _getUrls(config, serviceUrl) {
const {SEN} = Help4.widget.companionCore;
const {WHATSNEW_SCREEN_ID} = Help4.widget.help.CatalogueBackend;
const query = {};
const {playbackTag, screenId} = config.core;
query.locale = SEN.getLanguages(config);
query.appUrl = [screenId, screenId + WHATSNEW_SCREEN_ID];
['product', 'version', 'system', 'solution'].forEach(key => query[key] = config.core[key]);
const url = '/.catalogue?' + encodeURIComponent(Help4.JSON.stringify(query));
const serverBaseUrl = SEN.getServerBaseUrl(serviceUrl);
const urlSuffix = serviceUrl.substring(serverBaseUrl.length);
const pubUrl = SEN.createPubUrl({serverUrl: urlSuffix, tag: playbackTag}) + url;
const headUrl = urlSuffix + url;
return {serverBaseUrl, pubUrl, headUrl};
}
}
})();