%PDF- %PDF-
| Direktori : /home/bitrix/www/bitrix/js/landing/ui/panel/ |
| Current File : /home/bitrix/www/bitrix/js/landing/ui/panel/url_list.js |
;(function() {
"use strict";
BX.namespace("BX.Landing.UI.Panel");
var addClass = BX.Landing.Utils.addClass;
var removeClass = BX.Landing.Utils.removeClass;
var append = BX.Landing.Utils.append;
var onCustomEvent = BX.Landing.Utils.onCustomEvent;
var fireCustomEvent = BX.Landing.Utils.fireCustomEvent;
var setTextContent = BX.Landing.Utils.setTextContent;
var rect = BX.Landing.Utils.rect;
var create = BX.Landing.Utils.create;
var style = BX.Landing.Utils.style;
var join = BX.Landing.Utils.join;
var isNumber = BX.Landing.Utils.isNumber;
var isString = BX.Landing.Utils.isString;
var isPlainObject = BX.Landing.Utils.isPlainObject;
var isArray = BX.Landing.Utils.isArray;
var addQueryParams = BX.Landing.Utils.addQueryParams;
var Cache = BX.Landing.Cache;
var TYPE_PAGE = "landing";
var TYPE_BLOCK = "block";
var TYPE_SYSTEM = "system";
var SidebarButton = BX.Landing.UI.Button.SidebarButton;
/**
* Implements interface for works with links list
*
* @extends {BX.Landing.UI.Panel.Content}
*
* @param {string} id
* @param {object} [data]
* @constructor
*/
BX.Landing.UI.Panel.URLList = function(id, data)
{
BX.Landing.UI.Panel.Content.apply(this, arguments);
addClass(this.layout, "landing-ui-panel-url-list");
addClass(this.overlay, "landing-ui-panel-url-list-overlay");
addClass(this.overlay, "landing-ui-hide");
this.overlay.hidden = true;
this.overlay.dataset.isShown = "false";
// Bind on block events
onCustomEvent("BX.Landing.Block:init", this.refresh.bind(this));
onCustomEvent("BX.Landing.Block:remove", this.refresh.bind(this));
// Append panel
append(this.layout, document.body);
// Make loader
this.loader = new BX.Loader({target: this.content});
this.promiseResolve = (function() {});
this.layout.hidden = true;
this.isNeedLoad = true;
this.cache = new Cache();
};
/**
* Gets instance
* @returns {BX.Landing.UI.Panel.URLList}
*/
BX.Landing.UI.Panel.URLList.getInstance = function()
{
if (!BX.Landing.UI.Panel.URLList.instance)
{
BX.Landing.UI.Panel.URLList.instance = new BX.Landing.UI.Panel.URLList("url_list");
}
return BX.Landing.UI.Panel.URLList.instance;
};
/**
* Stores instance
* @static
* @type {BX.Landing.UI.Panel.URLList}
*/
BX.Landing.UI.Panel.URLList.instance = null;
BX.Landing.UI.Panel.URLList.prototype = {
constructor: BX.Landing.UI.Panel.URLList,
__proto__: BX.Landing.UI.Panel.Content.prototype,
/**
* Refresh cached values
*/
refresh: function()
{
this.isNeedLoad = true;
},
/**
* Shows loader
*/
showLoader: function()
{
this.loader.show(this.content);
},
/**
* Shows panel
* @param {String} view - landings|blocks
* @param {object} options
* @return {Promise}
*/
show: function(view, options)
{
BX.Landing.UI.Panel.Content.prototype.show.call(this);
this.clear();
this.showLoader();
if (view === TYPE_PAGE)
{
removeClass(this.layout, "landing-ui-panel-url-list-blocks");
setTextContent(this.title, BX.message("LANDING_LINKS_LANDINGS_TITLE"));
this.showSites(options);
}
else
{
setTextContent(this.title, BX.message("LANDING_LINKS_BLOCKS_TITLE"));
this.showBlocks(options);
}
return new Promise(function(resolve) {
this.promiseResolve = resolve;
}.bind(this));
},
/**
* Shows sites list
* @param {object} options
*/
showSites: function(options)
{
var currentSiteId = options.siteId;
void style(this.layout, {
width: null
});
void this.getSites(options).then(function(sites) {
this.appendSidebarButton(
new SidebarButton("current_site", {
text: BX.message("LANDING_LINKS_PANEL_CURRENT_SITE")
})
);
sites.forEach(function(site) {
// noinspection EqualityComparisonWithCoercionJS
if (parseInt(site.ID) == currentSiteId)
{
this.appendSidebarButton(
new SidebarButton(site.ID, {
text: site.TITLE,
onClick: this.onSiteClick.bind(this, site.ID, options.enableAreas),
child: true,
active: true
})
);
}
}, this);
this.getLandings(currentSiteId).then(function(landings) {
if (isPlainObject(landings))
{
landings = Object.keys(landings).reduce(function(acc, key) {
if (isPlainObject(landings[key]) && isArray(landings[key].result))
{
acc = acc.concat(landings[key].result);
}
return acc;
}, []);
}
landings.forEach(function(landing) {
if (!landing.IS_AREA || (landing.IS_AREA && options.enableAreas))
{
this.appendCard(
new BX.Landing.UI.Card.LandingPreviewCard({
title: landing.TITLE,
description: landing.DESCRIPTION,
preview: landing.PREVIEW,
onClick: this.onLandingClick.bind(this, landing.ID, landing.TITLE)
})
)
}
}, this);
var systemPages = this.getSystemPages();
Object.keys(systemPages).forEach(function(key) {
var page = systemPages[key];
this.appendCard(
new BX.Landing.UI.Card.LandingPreviewCard({
title: page.name,
description: page.description,
preview: page.preview,
onClick: this.onSystemClick.bind(this, key, page.name)
})
)
}, this);
this.loader.hide();
}.bind(this));
if (!options.currentSiteOnly)
{
this.appendSidebarButton(
new SidebarButton("my_sites", {
text: BX.message("LANDING_LINKS_PANEL_MY_SITES")
})
);
sites.forEach(function(site) {
this.appendSidebarButton(
new SidebarButton(site.ID, {
text: site.TITLE,
onClick: this.onSiteClick.bind(this, site.ID, options.enableAreas),
child: true
})
);
}, this);
}
}.bind(this));
},
getSystemPages: function()
{
var result;
try
{
result = BX.Landing.Main.getInstance().options.syspages;
if (!isPlainObject(result))
{
result = {};
}
}
catch(err)
{
result = {};
}
return result;
},
/**
* @private
* @return {BX.Landing.UI.Button.SidebarButton}
*/
createCurrentSiteButton: function()
{
return new SidebarButton("current_site", {
text: BX.message("LANDING_LINKS_PANEL_CURRENT_SITE")
});
},
/**
* Shows blocks list
* @param {object} options
*/
showBlocks: function(options)
{
var currentLandingId = options.landingId;
var currentSiteId = options.siteId;
void style(this.layout, {
width: "880px"
});
this.getSites(options)
.then(function(sites) {
this.appendSidebarButton(
this.createCurrentSiteButton()
);
var sitesIds = sites.map(function(site) {
return site.ID;
}, this);
return this.getLandings(sitesIds)
.then(function(landings) {
return sites.reduce(function(result, site, index) {
result[site.ID] = {site: site, landings: landings[site.ID].result};
return result;
}, {});
});
}.bind(this))
.then(function(result) {
result[currentSiteId].landings.forEach(function(landing) {
var active = parseInt(landing.ID) === parseInt(currentLandingId);
var button = this.createLandingSidebarButton(landing, active);
this.appendSidebarButton(button);
if (active)
{
button.layout.click();
}
}, this);
Object.keys(result).forEach(function(siteId) {
if (parseInt(siteId) !== parseInt(currentSiteId))
{
var site = result[siteId].site;
this.appendSidebarButton(
this.createSiteSidebarButton(site)
);
result[siteId].landings.forEach(function(landing) {
this.appendSidebarButton(
this.createLandingSidebarButton(landing)
);
}, this)
}
}, this);
}.bind(this));
},
createLandingSidebarButton: function(landing, active)
{
return (
new SidebarButton(landing.ID, {
text: landing.TITLE,
onClick: this.onLandingChange.bind(this, landing),
child: true,
active: active
})
);
},
createSiteSidebarButton: function(site)
{
return (
new SidebarButton(site.ID, {
text: site.TITLE,
child: false,
active: false
})
);
},
onLandingChange: function(landing, event)
{
this.currentSelectedLanding = landing;
this.sidebarButtons.forEach(function(button) {
if (button.layout === event.currentTarget)
{
button.activate();
return;
}
button.deactivate();
});
this.showPreviewLoader()
.then(this.createIframeIfNeed())
.then(this.loadPreviewSrc(this.buildLandingPreviewUrl(landing)))
.then(this.hidePreviewLoader())
},
buildLandingPreviewUrl: function(landing)
{
var editorUrl = BX.Landing.Main.getInstance().options.params.sef_url.landing_view;
editorUrl = editorUrl.replace("#site_show#", landing.SITE_ID);
editorUrl = editorUrl.replace("#landing_edit#", landing.ID);
return addQueryParams(editorUrl, {
forceLoad: true,
landing_mode: "edit"
});
},
loadPreviewSrc: function(src)
{
return function()
{
return new Promise(function(resolve) {
if (this.previewFrame.src !== src)
{
this.previewFrame.src = src;
this.previewFrame.onload = function() {
var contentDocument = this.previewFrame.contentDocument;
BX.Landing.Utils.removePanels(contentDocument);
[].slice.call(contentDocument.querySelectorAll(".block-wrapper"))
.forEach(function(wrapper) {
wrapper.classList.add("landing-ui-block-selectable-overlay");
wrapper.addEventListener("click", function(event) {
event.preventDefault();
this.onBlockClick(parseInt(wrapper.id.replace("block", "")), event);
}.bind(this));
}, this);
resolve(this.previewFrame);
}.bind(this);
return;
}
resolve(this.previewFrame);
}.bind(this));
}.bind(this)
},
showPreviewLoader: function()
{
if (!this.loader)
{
this.loader = new BX.Loader();
}
if (this.previewFrameWrapper)
{
void style(this.previewFrameWrapper, {
opacity: 0
});
}
return new Promise(function(resolve) {
void this.loader.show(this.content);
resolve();
}.bind(this));
},
hidePreviewLoader: function()
{
return function()
{
void style(this.previewFrameWrapper, {
opacity: null
});
return this.loader.hide();
}.bind(this);
},
createIframeIfNeed: function()
{
return function()
{
new Promise(function(resolve) {
if (!this.previewFrame)
{
this.previewFrame = create("iframe", {});
this.previewFrameWrapper = create("div", {
attrs: {style: "width: 100%; height: 100%; overflow: hidden;"}
});
this.previewFrameWrapper.appendChild(this.previewFrame);
this.content.innerHTML = "";
this.content.appendChild(this.previewFrameWrapper);
this.showPreviewLoader();
requestAnimationFrame(function() {
var containerWidth = this.content.clientWidth - 40;
void style(this.previewFrame, {
"width": "1000px",
"height": "calc((100vh - 113px) * (100 / "+((containerWidth/1000)*100)+"))",
"transform": "scale("+(containerWidth/1000)+") translateZ(0)",
"transform-origin": "top left",
"border": "none"
});
}.bind(this));
}
resolve(this.previewFrame);
}.bind(this));
}.bind(this)
},
/**
* Handle block click event
* @param {Number|String} id
* @param event
*/
onBlockClick: function(id, event)
{
if (event.isTrusted)
{
this.getBlocks(this.currentSelectedLanding.ID)
.then(function(blocks) {
var currentBlock = blocks.find(function(block) {
return block.id === id;
});
if (currentBlock)
{
this.onChange({
type: TYPE_BLOCK,
id: currentBlock.id,
name: currentBlock.name,
alias: currentBlock.alias
});
}
}.bind(this));
}
},
/**
* Handle landing click event
* @param {Number|String} id
* @param {String} name
*/
onLandingClick: function(id, name)
{
this.onChange({type: TYPE_PAGE, id: id, name: name});
},
/**
* Handle system click event
* @param {Number|String} id
* @param {String} name
*/
onSystemClick: function(id, name)
{
this.onChange({type: TYPE_SYSTEM, id: "_" + id, name: name});
},
/**
* Handle site click event
* @param {?boolean} enableAreas
* @param {object} event
* @param {Number|String} siteId
*/
onSiteClick: function(siteId, enableAreas, event)
{
this.sidebarButtons.forEach(function(button) {
if (button.layout === event.currentTarget)
{
button.activate();
}
else
{
button.deactivate();
}
});
this.content.innerHTML = "";
this.showLoader();
this.getLandings(siteId).then(function(landings) {
if (isPlainObject(landings))
{
landings = Object.keys(landings).reduce(function(acc, key) {
if (isPlainObject(landings[key]) && isArray(landings[key].result))
{
acc = acc.concat(landings[key].result);
}
return acc;
}, []);
}
landings.forEach(function(landing) {
if (!landing.IS_AREA || (landing.IS_AREA && enableAreas))
{
this.appendCard(this.createLandingPreview(landing));
}
}, this);
this.loader.hide();
}.bind(this));
},
/**
* Creates landing preview
* @param {{
* ID: Number|String,
* TITLE: String,
* DESCRIPTION: String,
* PREVIEW: String
* }} options
* @return {BX.Landing.UI.Card.LandingPreviewCard}
*/
createLandingPreview: function(options)
{
return new BX.Landing.UI.Card.LandingPreviewCard({
title: options.TITLE,
description: options.DESCRIPTION,
preview: options.PREVIEW,
onClick: this.onLandingClick.bind(this, options.ID, options.TITLE)
});
},
/**
* Creates block preview
* @param {{id: Number|String, name: String}} options
* @return {BX.Landing.UI.Card.BlockHTMLPreview}
*/
createBlockPreview: function(options)
{
return new BX.Landing.UI.Card.BlockHTMLPreview({
content: options.id,
onClick: this.onBlockClick.bind(this, options.id, options.name, options.alias)
});
},
/**
* @param {object} options
* @return {Promise<Object, Object>}
*/
getSites: function(options)
{
if (this.cache.has(options))
{
return Promise.resolve(this.cache.get(options));
}
return BX.Landing.Backend.getInstance()
.action("Site::getList", {
params: {
order: {ID: "DESC"},
filter: options.filter
}
})
.then(function(response) {
this.cache.add(options, response);
return response;
}.bind(this));
},
/**
* Gets landings list of site
* @param {number|string|Array<string|number>} [siteId]
* @param {object} options
* @returns {Promise.<Object>}
*/
getLandings: function(siteId, options)
{
siteId = isNumber(siteId) || isString(siteId) || isArray(siteId) ? siteId : options.siteId;
var cacheKey = isArray(siteId) ? siteId.join(',') : siteId;
if (this.cache.has("getLandings" + cacheKey))
{
return Promise.resolve(this.cache.get("getLandings" + cacheKey));
}
if (isArray(siteId))
{
var batchData = siteId.reduce(function(acc, item) {
acc[item] = {
action: "Landing::getList",
data: {
params: {
filter: {SITE_ID: item},
order: {ID: "DESC"},
get_preview: true,
check_area: 1
}
}
};
return acc;
}, {});
return BX.Landing.Backend.getInstance()
.batch("Landing::getList", batchData)
.then(function(response) {
this.cache.add("getLandings" + cacheKey, response);
return response;
}.bind(this));
}
return BX.Landing.Backend.getInstance()
.action("Landing::getList", {
params: {
filter: {SITE_ID: siteId},
order: {ID: "DESC"},
get_preview: true,
check_area: 1
}
})
.then(function(response) {
this.cache.add("getLandings" + cacheKey, response);
return response;
}.bind(this))
},
/**
* Gets landing by id
* @param {Number|String} landingId
* @param {object} options
* @return {Promise<Object, Object>}
*/
getLanding: function(landingId, options)
{
if (this.cache.has(["getLanding" + landingId, options]))
{
return Promise.resolve(this.cache.get(["getLanding" + landingId, options]));
}
return BX.Landing.Backend.getInstance()
.action("Landing::getList", {params: {
filter: {ID: landingId},
get_preview: true
}})
.then(function(response) {
this.cache.add(["getLanding" + landingId, options], response);
return response;
}.bind(this))
},
/**
* Gets landing blocks by landing id
* @param {Number|String} [landingId]
* @param {object} options
* @return {Promise<Object, Object>}
*/
getBlocks: function(landingId, options)
{
landingId = isNumber(landingId) || isString(landingId) ? landingId : options.landingId;
if (this.cache.has(["getBlocks" + landingId, options]))
{
var cacheResult = this.cache.get(["getBlocks" + landingId, options]);
if (cacheResult &&
typeof cacheResult === "object" &&
typeof cacheResult.then === "function")
{
return cacheResult;
}
return Promise.resolve(cacheResult);
}
var resultPromise = BX.Landing.Backend.getInstance()
.action("Block::getList", {
lid: landingId,
params: {
get_content: true,
edit_mode: true
}
})
.then(function(response) {
this.cache.set(["getBlocks" + landingId, options], response);
return response;
}.bind(this));
this.cache.set(["getBlocks" + landingId, options], resultPromise);
return resultPromise;
},
getBlock: function(id)
{
var cacheKey = "getBlocks" + id;
if (this.cache.has(cacheKey))
{
var cacheResult = this.cache.get(cacheKey);
if (cacheResult &&
typeof cacheResult === "object" &&
typeof cacheResult.then === "function")
{
return cacheResult;
}
return Promise.resolve(cacheResult);
}
var resultPromise = BX.Landing.Backend.getInstance()
.action("Block::getById", {
block: id,
params: {
edit_mode: true
}
})
.then(function(response) {
this.cache.set(cacheKey, response);
return response;
}.bind(this));
this.cache.set(cacheKey, resultPromise);
return resultPromise;
},
/**
* Gets all entries
* @returns {Promise<object[]>}
*/
getEntries: function()
{
return new Promise(function(resolve) {
if (this.isNeedLoad)
{
this.getLandings().then(function(landings) {
var all = Promise.all(landings.map(function(landing) {
return this.getBlocks(landing.ID);
}, this));
all.then(function(result) {
var value = landings.map(function(item, index) {
var resItem = result[index];
if (isPlainObject(resItem))
{
var keys = Object.keys(resItem);
resItem = keys.map(function(block) {
return result[index][block];
});
}
item.blocks = resItem;
return item;
});
this.lastEntries = value;
this.isNeedLoad = false;
resolve(value);
}.bind(this));
}.bind(this));
}
else
{
resolve(this.lastEntries);
}
}.bind(this));
},
onChange: function(value)
{
this.promiseResolve(value);
this.hide();
},
hide: function()
{
this.previewFrame = null;
return BX.Landing.UI.Panel.Content.prototype.hide.call(this);
}
}
})();