Роль: Администратор
<script>
(() => {
const initWidget = () => {
const urls = {
css: 'https://service.voda-sale.ru/vs/main.css',
react: 'https://service.voda-sale.ru/assets/libs/react/react.production.min.js',
reactDom: 'https://service.voda-sale.ru/assets/libs/react/react-dom.production.min.js',
widget: 'https://service.voda-sale.ru/vs/indexES5.js'
}
const fetchResource = (url) => fetch(url, {mode: 'cors'}).then(r => {
if (!r.ok) throw new Error(`Failed to load ${url}`)
return r.text()
})
// 1. Создаем или находим контейнер
let root = document.getElementById('go-core-frame-on-react-root')
if (!root) {
root = document.createElement('div')
root.id = 'go-core-frame-on-react-root'
root.setAttribute('data-connect-go-core-query', 'https://service.voda-sale.ru')
document.body.prepend(root)
}
// 1.1. Неблокирующая подгрузка CSS из urls.css (можно перечислить через запятую)
const loadCSS = (href) => {
if (!href) return
const url = href.trim()
if (!url) return
// проверка на дубликаты
const exists = Array.from(document.getElementsByTagName('link')).some(l => l.rel.includes('stylesheet') && l.href === url)
if (exists) return
// Неблокирующая загрузка: сначала preload, затем превращаем в stylesheet
const link = document.createElement('link')
link.rel = 'preload'
link.as = 'style'
link.href = url
link.onload = function () {
// После загрузки меняем на полноценный stylesheet
this.onload = null
this.rel = 'stylesheet'
}
link.onerror = function () {
// Фолбэк: если preload не поддерживается/упал — создаем обычный stylesheet через media-хак
const css = document.createElement('link')
css.rel = 'stylesheet'
css.href = url
css.media = 'print'
css.onload = function () { this.media = 'all' }
document.head.appendChild(css)
this.remove()
}
document.head.appendChild(link)
}
if (urls.css) {
// Строка может содержать несколько URL через запятую
urls.css.split(',').forEach(loadCSS)
}
// 2. Загружаем все в параллели
Promise.all([
fetchResource(urls.react),
fetchResource(urls.reactDom),
fetchResource(urls.widget)
]).then(([react, reactDom, widget]) => {
// 3. Выполнение скриптов в правильном порядке
const executeScript = (code) => {
const script = document.createElement('script')
script.textContent = code
document.head.appendChild(script)
}
executeScript(react)
executeScript(reactDom)
const widgetBaseUrl = urls.widget.substring(0, urls.widget.lastIndexOf('/') + 1)
const fullCode = `
window.__webpack_public_path__ = "${widgetBaseUrl}";
${widget}
`
executeScript(fullCode)
}).catch(err => console.error('Error loading widget resources:', err))
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', initWidget)
} else {
initWidget()
}
})()
</script>
<button class="c-button" onClick="triggerInitGoCoreWidget()">Показать виджет</button>
<script>
(() => {
const initWidget = () => {
const urls = {
css: 'https://service.voda-sale.ru/vs/main.css',
react: 'https://service.voda-sale.ru/assets/libs/react/react.production.min.js',
reactDom: 'https://service.voda-sale.ru/assets/libs/react/react-dom.production.min.js',
widget: 'https://service.voda-sale.ru/vs/indexES5.js'
}
const fetchResource = (url) => fetch(url, {mode: 'cors'}).then(r => {
if (!r.ok) throw new Error(`Failed to load ${url}`)
return r.text()
})
// 1. Создаем или находим контейнер
let root = document.getElementById('go-core-frame-on-react-root')
if (!root) {
root = document.createElement('div')
root.id = 'go-core-frame-on-react-root'
root.setAttribute('data-auto-start', 'false')
root.setAttribute('data-connect-go-core-query', 'https://service.voda-sale.ru')
document.body.prepend(root)
}
// 1.1. Неблокирующая подгрузка CSS из urls.css (можно перечислить через запятую)
const loadCSS = (href) => {
if (!href) return
const url = href.trim()
if (!url) return
// проверка на дубликаты
const exists = Array.from(document.getElementsByTagName('link')).some(l => l.rel.includes('stylesheet') && l.href === url)
if (exists) return
// Неблокирующая загрузка: сначала preload, затем превращаем в stylesheet
const link = document.createElement('link')
link.rel = 'preload'
link.as = 'style'
link.href = url
link.onload = function () {
// После загрузки меняем на полноценный stylesheet
this.onload = null
this.rel = 'stylesheet'
}
link.onerror = function () {
// Фолбэк: если preload не поддерживается/упал — создаем обычный stylesheet через media-хак
const css = document.createElement('link')
css.rel = 'stylesheet'
css.href = url
css.media = 'print'
css.onload = function () { this.media = 'all' }
document.head.appendChild(css)
this.remove()
}
document.head.appendChild(link)
}
if (urls.css) {
// Строка может содержать несколько URL через запятую
urls.css.split(',').forEach(loadCSS)
}
// 2. Загружаем все в параллели
Promise.all([
fetchResource(urls.react),
fetchResource(urls.reactDom),
fetchResource(urls.widget)
]).then(([react, reactDom, widget]) => {
// 3. Выполнение скриптов в правильном порядке
const executeScript = (code) => {
const script = document.createElement('script')
script.textContent = code
document.head.appendChild(script)
}
executeScript(react)
executeScript(reactDom)
const widgetBaseUrl = urls.widget.substring(0, urls.widget.lastIndexOf('/') + 1)
const fullCode = `
window.__webpack_public_path__ = "${widgetBaseUrl}";
${widget}
`
executeScript(fullCode)
}).catch(err => console.error('Error loading widget resources:', err))
}
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', initWidget)
} else {
initWidget()
}
})()
function triggerInitGoCoreWidget() {
if (document.getElementById('go-core-frame-on-react-root')) {
const _tiny = document.querySelector('.voda-show-btn-tiny.voda-show-btn-tiny_active')
if (_tiny) _tiny.click()
}
document.dispatchEvent(new Event('goCore.init'))
}
</script>
В текущей версии ПО, создание и блокировка консультантов а также их подключение к сайту производиться через обращение в поддержку support@voda-sale.ru
В таблице представлен список подключенных, активных консультантов.