(function () {
function qs(sel, root) { return (root || document).querySelector(sel) }
function qsa(sel, root) { return (root || document).querySelectorAll(sel) }
var API_URL = '/ajax/partner_settings_api.php'
var MODAL_URL = '/ajax/partner_settings_modal.php'
var CK_SRC = '/js/ckeditor/ckeditor.js'
function apiPost(fd, cb) {
var xhr = new XMLHttpRequest()
xhr.open('POST', API_URL, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
if (xhr.status !== 200) return cb(null)
var data = null
try { data = JSON.parse(xhr.responseText)
} catch (e) {}
cb(data)
}
xhr.send(fd)
}
function removeModal() {
var root = qs('#partnerSettingsRoot')
if (root && root._ps_restoreOverflow) {
try { root._ps_restoreOverflow() } catch (e) {}
}
if (root && root.parentNode) root.parentNode.removeChild(root)
}
function copyText(text) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text)
return
}
var ta = document.createElement('textarea')
ta.value = text
ta.style.position = 'fixed'
ta.style.left = '-9999px'
document.body.appendChild(ta)
ta.focus()
ta.select()
try { document.execCommand('copy') } catch (e) {}
document.body.removeChild(ta)
}
function setHidden(el, hidden) {
if (!el) return
var cls = el.className || ''
var has = cls.indexOf('partner-settings-hidden') !== -1
if (hidden && !has) el.className = (cls + ' partner-settings-hidden').replace(/\s+/g, ' ').trim()
if (!hidden && has) el.className = cls.replace(/\bpartner-settings-hidden\b/g, '').replace(/\s+/g, ' ').trim()
}
function getActivePane(root) {
var panes = qsa('[data-ps-pane]', root)
var i = 0
while (i < panes.length) {
var p = panes[i]
if (p.style.display !== 'none') return p
i++
}
return root
}
function showOk(root, text) {
var pane = getActivePane(root)
var ok = qs('[data-ps-ok]', pane)
var err = qs('[data-ps-err]', pane)
if (err) { err.innerHTML = ''; setHidden(err, true) }
if (ok) { ok.textContent = text || ''; setHidden(ok, !text) }
}
function showErr(root, html) {
var pane = getActivePane(root)
var ok = qs('[data-ps-ok]', pane)
var err = qs('[data-ps-err]', pane)
if (ok) { ok.textContent = ''; setHidden(ok, true) }
if (err) { err.innerHTML = html || ''; setHidden(err, !html) }
}
function fullUrlFrom(root, slug) {
var base = root.getAttribute('data-ps-base')
if (!base) base = 'https://partner.joywork.ru/'
var agencyId = root.getAttribute('data-ps-agency-id') || ''
slug = (slug || '').trim()
if (slug) return base.replace(/\/+$/, '/') + encodeURIComponent(slug)
return base.replace(/\/+$/, '/') + '?agency_id=' + encodeURIComponent(String(agencyId))
}
function svgTrash18() {
return ''
}
function svgEdit15() {
return ''
}
function svgFile22() {
return ''
}
function svgDownload18() {
return ''
}
function updateOuterPartnerLink(fullUrl) {
if (!fullUrl) return
var outerRoot = qs('.partner-settings-block')
if (!outerRoot) return
var a = qs('a', outerRoot)
if (!a) return
a.setAttribute('href', fullUrl)
a.textContent = fullUrl
}
function bindTabs(root) {
var tabs = qs('[data-ps-tabs]', root)
if (!tabs) return
function activate(tab) {
var pane = qs('[data-ps-pane="' + tab + '"]', root)
if (!pane) return false
var allTabs = qsa('.partner-settings-tab', tabs)
for (var i = 0; i < allTabs.length; i++) {
allTabs[i].className = allTabs[i].className.replace(/\bis-active\b/g, '').replace(/\s+/g, ' ').trim()
}
var btn = qs('[data-ps-tab="' + tab + '"]', tabs)
if (btn) btn.className = (btn.className + ' is-active').replace(/\s+/g, ' ').trim()
var panes = qsa('[data-ps-pane]', root)
for (var j = 0; j < panes.length; j++) panes[j].style.display = 'none'
pane.style.display = 'block'
var ok = qs('[data-ps-ok]', pane)
var err = qs('[data-ps-err]', pane)
if (ok) { ok.textContent = ''; setHidden(ok, true) }
if (err) { err.innerHTML = ''; setHidden(err, true) }
if (tab === 'materials') {
if (window.partnerSettingsMaterialsLoad) window.partnerSettingsMaterialsLoad()
}
if (tab === 'news') {
if (window.partnerSettingsNewsLoad) window.partnerSettingsNewsLoad()
}
return true
}
tabs.addEventListener('click', function (e) {
var btn = e.target
while (btn && btn !== tabs && !btn.getAttribute('data-ps-tab')) btn = btn.parentNode
if (!btn || btn === tabs) return
var tab = btn.getAttribute('data-ps-tab')
activate(tab)
})
var def = root.getAttribute('data-ps-default-tab')
if (!def) def = 'url'
if (!activate(def)) {
var first = qs('[data-ps-tab]', tabs)
if (first) {
var t = first.getAttribute('data-ps-tab') || ''
activate(t)
}
}
}
function bindClose(root) {
var closeBtns = qsa('[data-ps-close]', root)
for (var i = 0; i < closeBtns.length; i++) closeBtns[i].addEventListener('click', removeModal)
}
function bindUrlRow(root) {
var inp = qs('[data-ps-url-input]', root)
var copyBtn = qs('[data-ps-url-copy]', root)
var urlLink = qs('[data-ps-url-link]', root)
if (!inp) return
inp.setAttribute('data-ps-original', inp.value || '')
root._ps_url_dirty = false
inp.addEventListener('input', function () {
var orig = inp.getAttribute('data-ps-original') || ''
root._ps_url_dirty = (String(inp.value || '').trim() !== String(orig).trim())
})
if (copyBtn) {
copyBtn.addEventListener('click', function () {
var slugVal = inp ? inp.value : ''
var url = fullUrlFrom(root, slugVal)
copyText(url)
showOk(root, 'Скопировано')
})
}
root._ps_save_url = function (cb) {
showOk(root, '')
showErr(root, '')
var slug = String(inp.value || '').trim()
var fd = new FormData()
fd.append('action', 'url_save')
fd.append('partner_url', slug)
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
if (cb) cb(false)
return
}
inp.value = data.partner_url || ''
inp.setAttribute('data-ps-original', inp.value || '')
root._ps_url_dirty = false
if (urlLink && data.full_url) {
urlLink.setAttribute('href', data.full_url)
urlLink.textContent = data.full_url
}
if (data.full_url) updateOuterPartnerLink(data.full_url)
showOk(root, 'URL сохранён')
if (cb) cb(true)
})
}
}
function bindBottomSave(root) {
var btn = qs('.partner-settings-save', root)
if (!btn) return
function getActiveTabKey() {
var pane = getActivePane(root)
if (!pane || !pane.getAttribute) return ''
return pane.getAttribute('data-ps-pane') || ''
}
btn.addEventListener('click', function (e) {
e.preventDefault()
e.stopPropagation()
if (e.stopImmediatePropagation) e.stopImmediatePropagation()
var activeTab = getActiveTabKey()
if (activeTab === 'url') {
if (root._ps_url_dirty && typeof root._ps_save_url === 'function') {
root._ps_save_url(function (ok) {
if (ok) removeModal()
})
return
}
removeModal()
return
}
if (activeTab === 'materials') {
if (typeof root._ps_save_materials === 'function') {
root._ps_save_materials(function (ok) {
if (ok) removeModal()
})
return
}
removeModal()
return
}
removeModal()
}, true)
}
function bindMaterials(root) {
var listBox = qs('[data-ps-mat-list]', root)
var empty = qs('[data-ps-mat-empty]', root)
var addBtn = qs('[data-ps-mat-add-cat]', root)
if (!listBox) return
var state = {
categories: [],
openCatId: 0,
loaded: false,
editingCatId: 0,
editingTitle: '',
creating: false,
creatingTitle: '',
pendingUploads: {}
}
function renderUploadSummary(okCount, failedItems) {
showOk(root, '')
showErr(root, '')
if (okCount > 0) {
showOk(root, 'Загружено файлов: ' + okCount)
}
if (failedItems && failedItems.length) {
var html = 'Не загружено файлов: ' + failedItems.length
var i = 0
while (i < failedItems.length) {
var row = failedItems[i] || {}
var fname = String(row.file_name || 'Файл')
var msg = String(row.message || 'Ошибка загрузки файла')
html += '
• ' + fname.replace(//g, '>') + ': ' +
msg.replace(//g, '>')
i++
}
showErr(root, html)
}
}
function showDropError(catId, text) {
showErr(root, text || '')
}
function clearDropError(catId) {
showErr(root, '')
}
function extFromName(name) {
name = String(name || '')
var p = name.lastIndexOf('.')
if (p < 0) return ''
return name.slice(p + 1).toLowerCase().replace(/[^a-z0-9]/g, '')
}
function isAllowedExtFront(ext) {
var allowed = {
pdf:1, doc:1, docx:1, rtf:1, txt:1, xls:1, xlsx:1, csv:1, jpg:1, jpeg:1, png:1, webp:1
}
return !!allowed[ext]
}
function validateFilesFront(catId, files) {
var max = 20 * 1024 * 1024
var out = []
var i = 0
while (i < files.length) {
var f = files[i]
var ext = extFromName(f.name)
if (!isAllowedExtFront(ext)) {
showDropError(catId, 'Формат .' + (ext || 'unknown') + ' не поддерживается')
return null
}
if (Number(f.size || 0) > max) {
showDropError(catId, 'Файл слишком большой. Максимум 20 МБ')
return null
}
out.push(f)
i++
}
clearDropError(catId)
return out
}
function findCatById(id) {
var i = 0
while (i < state.categories.length) {
if (state.categories[i].id === id) return state.categories[i]
i++
}
return null
}
function ensurePendingBucket(catId) {
catId = String(catId)
if (!state.pendingUploads[catId]) state.pendingUploads[catId] = []
return state.pendingUploads[catId]
}
function addPendingUpload(catId, fileName) {
var uid = 'u_' + String(Date.now()) + '_' + String(Math.floor(Math.random() * 100000))
var bucket = ensurePendingBucket(catId)
bucket.push({
uid: uid,
name: String(fileName || 'Файл'),
percent: 0
})
return uid
}
function updatePendingUpload(catId, uid, percent) {
var bucket = ensurePendingBucket(catId)
var i = 0
while (i < bucket.length) {
if (bucket[i].uid === uid) {
bucket[i].percent = percent
return
}
i++
}
}
function removePendingUpload(catId, uid) {
var bucket = ensurePendingBucket(catId)
var next = []
var i = 0
while (i < bucket.length) {
if (bucket[i].uid !== uid) next.push(bucket[i])
i++
}
state.pendingUploads[String(catId)] = next
}
function clearPendingUploads(catId) {
state.pendingUploads[String(catId)] = []
}
function stopEditing() {
state.editingCatId = 0
state.editingTitle = ''
}
function startEditing(catId) {
var cat = findCatById(catId)
if (!cat) return
state.editingCatId = catId
state.editingTitle = cat.title || ''
state.creating = false
state.creatingTitle = ''
}
function startCreating() {
state.creating = true
state.creatingTitle = ''
stopEditing()
}
function stopCreating() {
state.creating = false
state.creatingTitle = ''
}
function setEmptyVisible(v) {
if (!empty) return
if (v) empty.style.display = 'block'
if (!v) empty.style.display = 'none'
}
function focusEditingInput() {
if (!state.editingCatId) return
var inp = qs('input[data-cat-input="' + String(state.editingCatId) + '"]', listBox)
if (!inp) return
inp.focus()
inp.select()
}
function focusCreatingInput() {
if (!state.creating) return
var inp = qs('input[data-cat-create-input="1"]', listBox)
if (!inp) return
inp.focus()
inp.select()
}
function render() {
listBox.innerHTML = ''
if (!state.categories.length && !state.creating) {
setEmptyVisible(true)
} else {
setEmptyVisible(false)
}
var i = 0
while (i < state.categories.length) {
var c = state.categories[i]
var opened = false
if (c.id === state.openCatId) opened = true
var cat = document.createElement('div')
cat.className = 'ps-mat2__cat'
var row = document.createElement('div')
row.className = 'ps-mat2__row'
row.setAttribute('data-cat-id', String(c.id))
var name = document.createElement('div')
name.className = 'ps-mat2__name'
var actions = document.createElement('div')
actions.className = 'ps-mat2__actions'
if (c.id === state.editingCatId) {
var inp = document.createElement('input')
inp.type = 'text'
inp.className = 'ps-mat2__input'
inp.value = state.editingTitle
inp.setAttribute('data-cat-input', String(c.id))
name.appendChild(inp)
var save = document.createElement('button')
save.type = 'button'
save.className = 'ps-mat2__icon ps-mat2__icon--save'
save.textContent = '✓'
save.setAttribute('data-cat-save', String(c.id))
var cancel = document.createElement('button')
cancel.type = 'button'
cancel.className = 'ps-mat2__icon'
cancel.textContent = '×'
cancel.setAttribute('data-cat-cancel', String(c.id))
actions.appendChild(save)
actions.appendChild(cancel)
} else {
name.textContent = c.title
name.setAttribute('data-cat-open', String(c.id))
name.style.cursor = 'pointer'
var edit = document.createElement('button')
edit.type = 'button'
edit.className = 'ps-mat2__icon'
edit.setAttribute('data-cat-edit', String(c.id))
edit.innerHTML = svgEdit15()
var del = document.createElement('button')
del.type = 'button'
del.className = 'ps-mat2__icon ps-mat2__icon--danger'
del.setAttribute('data-cat-del', String(c.id))
del.innerHTML = svgTrash18()
var op = document.createElement('button')
op.type = 'button'
op.className = 'ps-mat2__icon'
if (opened) op.textContent = '-'
if (!opened) op.textContent = '+'
op.setAttribute('data-cat-open', String(c.id))
actions.appendChild(edit)
actions.appendChild(del)
actions.appendChild(op)
}
row.appendChild(name)
row.appendChild(actions)
cat.appendChild(row)
if (opened) {
var body = document.createElement('div')
body.className = 'ps-mat2__body'
var files = document.createElement('div')
files.className = 'ps-mat2__files'
var pList = state.pendingUploads[String(c.id)] || []
var pListForEmpty = state.pendingUploads[String(c.id)] || []
if ((!c.files || !c.files.length) && !pListForEmpty.length) {
var fr = document.createElement('div')
fr.className = 'ps-mat2__file'
fr.style.paddingBottom = '10px'
var fn = document.createElement('div')
fn.className = 'ps-mat2__file-name'
fn.style.textDecoration = 'none'
fn.textContent = 'Файлы отсутствуют'
fr.appendChild(fn)
files.appendChild(fr)
} else {
var j = 0
while (j < c.files.length) {
var f = c.files[j]
var fr2 = document.createElement('div')
fr2.className = 'ps-mat2__file'
fr2.style.paddingBottom = '10px'
var open = document.createElement('a')
open.className = 'ps-mat2__file-open'
open.innerHTML = svgFile22()
if (f.file_url) {
open.href = f.file_url
open.target = '_blank'
open.rel = 'noopener'
} else {
open.href = 'javascript:void(0)'
}
var title = document.createElement('div')
title.className = 'ps-mat2__file-title'
title.textContent = f.file_name
var fa = document.createElement('div')
fa.className = 'ps-mat2__file-actions'
var dl = document.createElement('a')
dl.className = 'ps-mat2__file-download'
dl.innerHTML = svgDownload18()
if (f.file_url) {
dl.href = API_URL + '?action=materials_file_download&file_id=' + encodeURIComponent(String(f.id))
dl.setAttribute('download', f.file_name || 'file')
} else {
dl.href = 'javascript:void(0)'
}
var fd = document.createElement('button')
fd.type = 'button'
fd.className = 'ps-mat2__icon ps-mat2__icon--danger'
fd.setAttribute('data-file-del', String(f.id))
fd.innerHTML = svgTrash18()
fa.appendChild(dl)
fa.appendChild(fd)
fr2.appendChild(open)
fr2.appendChild(title)
fr2.appendChild(fa)
files.appendChild(fr2)
j++
}
}
var upl = document.createElement('div')
upl.className = 'ps-upl'
var uplInput = document.createElement('input')
uplInput.type = 'file'
uplInput.multiple = true
uplInput.className = 'ps-upl__input'
uplInput.setAttribute('data-upl-input', String(c.id))
var drop = document.createElement('div')
drop.className = 'ps-upl__drop'
drop.setAttribute('data-upl-drop', String(c.id))
var ic = document.createElement('div')
ic.className = 'ps-upl__icon'
ic.textContent = '↑'
var tt = document.createElement('div')
tt.className = 'ps-upl__title'
tt.textContent = 'Нажмите на эту область или перенесите в нее файл'
var hint = document.createElement('div')
hint.className = 'ps-upl__hint'
hint.textContent = 'Форматы: PDF, DOC, DOCX, RTF, TXT, XLS, XLSX, CSV, JPG, JPEG, PNG, WEBP. Максимум 20 МБ'
drop.appendChild(ic)
drop.appendChild(tt)
drop.appendChild(hint)
upl.appendChild(uplInput)
upl.appendChild(drop)
var pendingWrap = document.createElement('div')
pendingWrap.className = 'ps-mat2__files'
pendingWrap.style.marginTop = '8px'
var pList = state.pendingUploads[String(c.id)] || []
var pi = 0
while (pi < pList.length) {
var p = pList[pi]
var prow = document.createElement('div')
prow.className = 'ps-mat2__file'
prow.style.background = 'rgba(76, 175, 80, 0.12)'
prow.style.paddingBottom = '10px'
var ptitle = document.createElement('div')
ptitle.className = 'ps-mat2__file-title'
ptitle.textContent = p.name
var pRight = document.createElement('div')
pRight.className = 'ps-mat2__file-actions'
pRight.style.minWidth = '140px'
pRight.style.justifyContent = 'flex-end'
var pPercent = document.createElement('div')
pPercent.style.fontWeight = '700'
pPercent.style.fontSize = '12px'
pPercent.style.color = 'black'
pPercent.textContent = String(Math.max(0, Math.min(100, parseInt(p.percent, 10) || 0))) + '%'
pRight.appendChild(pPercent)
prow.appendChild(ptitle)
prow.appendChild(pRight)
pendingWrap.appendChild(prow)
pi++
}
if (pList.length) {
body.appendChild(pendingWrap)
}
body.appendChild(files)
body.appendChild(upl)
cat.appendChild(body)
}
listBox.appendChild(cat)
i++
}
if (state.creating) {
var catNew = document.createElement('div')
catNew.className = 'ps-mat2__cat'
var rowNew = document.createElement('div')
rowNew.className = 'ps-mat2__row'
var nameNew = document.createElement('div')
nameNew.className = 'ps-mat2__name'
var inpNew = document.createElement('input')
inpNew.type = 'text'
inpNew.className = 'ps-mat2__input'
inpNew.value = state.creatingTitle
inpNew.setAttribute('data-cat-create-input', '1')
nameNew.appendChild(inpNew)
var actionsNew = document.createElement('div')
actionsNew.className = 'ps-mat2__actions'
var saveNew = document.createElement('button')
saveNew.type = 'button'
saveNew.className = 'ps-mat2__icon ps-mat2__icon--save'
saveNew.textContent = '✓'
saveNew.setAttribute('data-cat-create-save', '1')
var cancelNew = document.createElement('button')
cancelNew.type = 'button'
cancelNew.className = 'ps-mat2__icon'
cancelNew.textContent = '×'
cancelNew.setAttribute('data-cat-create-cancel', '1')
actionsNew.appendChild(saveNew)
actionsNew.appendChild(cancelNew)
rowNew.appendChild(nameNew)
rowNew.appendChild(actionsNew)
catNew.appendChild(rowNew)
listBox.appendChild(catNew)
}
focusEditingInput()
focusCreatingInput()
}
function load() {
var fd = new FormData()
fd.append('action', 'materials_list')
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
return
}
state.categories = data.categories || []
// если открытая категория удалена — закрыть
if (state.openCatId) {
var exists = false
var i = 0
while (i < state.categories.length) {
if (state.categories[i].id === state.openCatId) {
exists = true
break
}
i++
}
if (!exists) state.openCatId = 0
}
state.loaded = true
render()
})
}
function createCategory(title, cb) {
showOk(root, '')
showErr(root, '')
title = String(title || '').trim()
if (!title) { if (cb) cb(false); return }
var fd = new FormData()
fd.append('action', 'materials_category_create')
fd.append('title', title)
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
if (cb) cb(false)
return
}
stopCreating()
state.openCatId = data.id
state.loaded = false
load()
if (cb) cb(true)
})
}
function saveCategoryTitle(catId, title, cb) {
showOk(root, '')
showErr(root, '')
title = String(title || '').trim()
if (!title) { if (cb) cb(false); return }
var fd = new FormData()
fd.append('action', 'materials_category_rename')
fd.append('category_id', String(catId))
fd.append('title', title)
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
if (cb) cb(false)
return
}
stopEditing()
state.loaded = false
load()
if (cb) cb(true)
})
}
function deleteCategory(catId) {
showOk(root, '')
showErr(root, '')
var fd = new FormData()
fd.append('action', 'materials_category_delete')
fd.append('category_id', String(catId))
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
return
}
if (state.openCatId === catId) state.openCatId = 0
if (state.editingCatId === catId) stopEditing()
state.loaded = false
load()
})
}
function uploadFiles(catId, files) {
showOk(root, '')
showErr(root, '')
clearDropError(catId)
if (!catId) return
if (!files || !files.length) return
// Открываем категорию и сразу показываем pending-элементы
state.openCatId = catId
var pendings = []
var i = 0
while (i < files.length) {
var f = files[i]
var uid = addPendingUpload(catId, f.name || 'Файл')
pendings.push({ uid: uid, file: f })
i++
}
render()
// Грузим КАЖДЫЙ файл отдельно, чтобы у каждого был свой %
var finished = 0
var uploadedOk = 0
var failedItems = []
function doneOne() {
finished++
if (finished >= pendings.length) {
state.loaded = false
load()
renderUploadSummary(uploadedOk, failedItems)
}
}
function uploadOne(item) {
var fd = new FormData()
fd.append('action', 'materials_files_upload')
fd.append('category_id', String(catId))
fd.append('files[]', item.file)
var xhr = new XMLHttpRequest()
xhr.open('POST', API_URL, true)
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
xhr.upload.onprogress = function (e) {
if (!e || !e.lengthComputable) return
var percent = 0
if (e.total > 0) {
percent = Math.round((e.loaded / e.total) * 100)
}
updatePendingUpload(catId, item.uid, percent)
render()
}
xhr.onreadystatechange = function () {
if (xhr.readyState !== 4) return
var data = null
try { data = JSON.parse(xhr.responseText) } catch (e) {}
// Убираем pending-элемент этого файла
removePendingUpload(catId, item.uid)
if (xhr.status !== 200 || !data || !data.ok) {
var msg = 'Ошибка загрузки файла'
if (data && data.error) msg = data.error
if (data && data.errors && data.errors.length && data.errors[0].message) {
msg = data.errors[0].message
}
failedItems.push({
file_name: (item.file && item.file.name) ? item.file.name : 'Файл',
message: msg
})
render()
doneOne()
return
}
if (data.errors && data.errors.length) {
var ei = 0
while (ei < data.errors.length) {
failedItems.push({
file_name: data.errors[ei].file_name || ((item.file && item.file.name) ? item.file.name : 'Файл'),
message: data.errors[ei].message || 'Ошибка загрузки файла'
})
ei++
}
}
if (data.created && data.created.length) {
uploadedOk += data.created.length
}
render()
doneOne()
}
xhr.onerror = function () {
removePendingUpload(catId, item.uid)
failedItems.push({
file_name: (item.file && item.file.name) ? item.file.name : 'Файл',
message: 'Ошибка сети при загрузке файла'
})
render()
doneOne()
}
xhr.send(fd)
}
var k = 0
while (k < pendings.length) {
uploadOne(pendings[k])
k++
}
}
function deleteFile(fileId) {
showOk(root, '')
showErr(root, '')
var fd = new FormData()
fd.append('action', 'materials_file_delete')
fd.append('file_id', String(fileId))
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
return
}
state.loaded = false
load()
})
}
function toggleOpen(catId) {
if (state.editingCatId) return
if (state.creating) return
if (state.openCatId === catId) {
state.openCatId = 0
} else {
state.openCatId = catId
}
render()
}
function closestAttr(el, attrName) {
var cur = el
while (cur && cur !== listBox) {
if (cur.getAttribute && cur.getAttribute(attrName)) return cur
cur = cur.parentNode
}
return null
}
window.partnerSettingsMaterialsLoad = function () {
if (!state.loaded) load()
}
root._ps_save_materials = function (cb) {
if (state.editingCatId) {
var cid = state.editingCatId
var inp = qs('input[data-cat-input="' + String(cid) + '"]', listBox)
var val = inp ? inp.value : state.editingTitle
saveCategoryTitle(cid, val || '', function (ok) {
if (cb) cb(!!ok)
})
return
}
if (state.creating) {
var inpNew = qs('input[data-cat-create-input="1"]', listBox)
var valNew = inpNew ? inpNew.value : state.creatingTitle
createCategory(valNew || '', function (ok) {
if (cb) cb(!!ok)
})
return
}
if (cb) cb(true)
}
if (addBtn) {
addBtn.addEventListener('click', function () {
showOk(root, '')
showErr(root, '')
startCreating()
render()
})
}
listBox.addEventListener('click', function (e) {
var t = e.target
var dz = closestAttr(t, 'data-upl-drop')
if (dz) {
var cidDz = parseInt(dz.getAttribute('data-upl-drop'), 10)
if (!cidDz) return
var inp = qs('input[data-upl-input="' + String(cidDz) + '"]', listBox)
if (inp) inp.click()
return
}
var btn = t
while (btn && btn !== listBox && !btn.getAttribute('data-cat-open') && !btn.getAttribute('data-cat-edit') && !btn.getAttribute('data-cat-del') && !btn.getAttribute('data-cat-save') && !btn.getAttribute('data-cat-cancel') && !btn.getAttribute('data-cat-create-save') && !btn.getAttribute('data-cat-create-cancel') && !btn.getAttribute('data-file-del')) {
btn = btn.parentNode
}
if (!btn || btn === listBox) return
var v
v = btn.getAttribute('data-cat-create-save')
if (v) {
var inpNew = qs('input[data-cat-create-input="1"]', listBox)
if (!inpNew) return
createCategory(inpNew.value || '')
return
}
v = btn.getAttribute('data-cat-create-cancel')
if (v) {
stopCreating()
render()
return
}
v = btn.getAttribute('data-cat-save')
if (v) {
var cidSave = parseInt(v, 10)
var inpSave = qs('input[data-cat-input="' + String(cidSave) + '"]', listBox)
if (!inpSave) return
saveCategoryTitle(cidSave, inpSave.value || '')
return
}
v = btn.getAttribute('data-cat-cancel')
if (v) {
stopEditing()
render()
return
}
v = btn.getAttribute('data-cat-edit')
if (v) {
var cidEdit = parseInt(v, 10)
startEditing(cidEdit)
render()
return
}
v = btn.getAttribute('data-cat-del')
if (v) {
var cidDel = parseInt(v, 10)
if (!cidDel) return
openConfirmModal({
title: 'Удаление категории',
text: 'Удалить категорию и все файлы внутри?',
okText: 'Удалить',
cancelText: 'Отмена',
onConfirm: function () {
deleteCategory(cidDel)
}
})
return
}
v = btn.getAttribute('data-cat-open')
if (v) {
var cidOpen = parseInt(v, 10)
toggleOpen(cidOpen)
return
}
v = btn.getAttribute('data-file-del')
if (v) {
var fid = parseInt(v, 10)
if (!fid) return
openConfirmModal({
title: 'Удаление файла',
text: 'Вы действительно хотите удалить файл?',
okText: 'Удалить',
cancelText: 'Отмена',
onConfirm: function () {
deleteFile(fid)
}
})
return
}
})
listBox.addEventListener('change', function (e) {
var t = e.target
if (!t || !t.getAttribute) return
var v = t.getAttribute('data-upl-input')
if (!v) return
var cid = parseInt(v, 10)
if (!cid) return
if (!t.files) return
var picked = []
var i = 0
while (i < t.files.length) {
picked.push(t.files[i])
i++
}
var validPicked = validateFilesFront(cid, picked)
t.value = ''
if (!validPicked) return
uploadFiles(cid, validPicked)
})
listBox.addEventListener('dragover', function (e) {
var dz = closestAttr(e.target, 'data-upl-drop')
if (!dz) return
e.preventDefault()
dz.className = (String(dz.className) + ' is-drag').replace(/\s+/g, ' ').trim()
})
listBox.addEventListener('dragleave', function (e) {
var dz = closestAttr(e.target, 'data-upl-drop')
if (!dz) return
dz.className = String(dz.className).replace(/\bis-drag\b/g, '').replace(/\s+/g, ' ').trim()
})
listBox.addEventListener('drop', function (e) {
var dz = closestAttr(e.target, 'data-upl-drop')
if (!dz) return
e.preventDefault()
dz.className = String(dz.className).replace(/\bis-drag\b/g, '').replace(/\s+/g, ' ').trim()
var cid = parseInt(dz.getAttribute('data-upl-drop'), 10)
if (!cid) return
var dt = e.dataTransfer
if (!dt) return
if (!dt.files) return
var dropped = []
var di = 0
while (di < dt.files.length) {
dropped.push(dt.files[di])
di++
}
var validDropped = validateFilesFront(cid, dropped)
if (!validDropped) return
uploadFiles(cid, validDropped)
})
listBox.addEventListener('keydown', function (e) {
var t = e.target
if (!t || !t.getAttribute) return
var catInputId = t.getAttribute('data-cat-input')
var createInput = t.getAttribute('data-cat-create-input')
if (createInput) {
if (e.keyCode === 13) {
e.preventDefault()
createCategory(t.value || '')
return
}
if (e.keyCode === 27) {
e.preventDefault()
stopCreating()
render()
return
}
return
}
if (!catInputId) return
var cid = parseInt(catInputId, 10)
if (!cid) return
if (e.keyCode === 13) {
e.preventDefault()
saveCategoryTitle(cid, t.value || '')
return
}
if (e.keyCode === 27) {
e.preventDefault()
stopEditing()
render()
}
})
}
function loadScriptOnce(src, cb) {
if (!src) { cb(false); return }
if (!window._ps_scripts) window._ps_scripts = {}
var st = window._ps_scripts[src]
if (st && st.state === 'loaded') { cb(true); return }
if (st && st.state === 'loading') { st.cbs.push(cb); return }
window._ps_scripts[src] = { state: 'loading', cbs: [cb] }
var s = document.createElement('script')
s.src = src
s.async = true
s.onload = function () {
var a = window._ps_scripts[src].cbs || []
window._ps_scripts[src].cbs = []
window._ps_scripts[src].state = 'loaded'
var i = 0
while (i < a.length) { a[i](true); i++ }
}
s.onerror = function () {
var a = window._ps_scripts[src].cbs || []
window._ps_scripts[src].cbs = []
window._ps_scripts[src].state = 'error'
var i = 0
while (i < a.length) { a[i](false); i++ }
}
document.head.appendChild(s)
}
function ensureCkEditor(cb) {
if (window.CKEDITOR) { cb(true); return }
loadScriptOnce(CK_SRC, function (ok) {
if (!ok) { cb(false); return }
if (!window.CKEDITOR) { cb(false); return }
cb(true)
})
}
function openNewsCreateModal(root, onSaved, editItem) {
if (qs('.ps-news-modal')) return
var isEdit = !!(editItem && editItem.id)
var overlayEl = document.createElement('div')
overlayEl.className = 'ps-news-modal'
var boxEl = document.createElement('div')
boxEl.className = 'ps-news-modal__box'
var headerEl = document.createElement('div')
headerEl.className = 'ps-news-modal__head'
var titleEl = document.createElement('div')
titleEl.className = 'ps-news-modal__title'
titleEl.textContent = isEdit ? 'Редактировать новость' : 'Новая новость'
var closeBtn = document.createElement('button')
closeBtn.type = 'button'
closeBtn.className = 'ps-news-modal__close'
closeBtn.textContent = '×'
headerEl.appendChild(titleEl)
headerEl.appendChild(closeBtn)
var bodyEl = document.createElement('div')
bodyEl.className = 'ps-news-modal__body'
var msgOk = document.createElement('div')
msgOk.className = 'ps-news-modal__msg ps-news-modal__msg--ok partner-settings-hidden'
msgOk.setAttribute('data-news-modal-ok', '1')
var msgErr = document.createElement('div')
msgErr.className = 'ps-news-modal__msg ps-news-modal__msg--err partner-settings-hidden'
msgErr.setAttribute('data-news-modal-err', '1')
function modalShowOk(text) {
if (msgErr) { msgErr.innerHTML = ''; setHidden(msgErr, true) }
if (msgOk) { msgOk.textContent = text || ''; setHidden(msgOk, !text) }
}
function modalShowErr(html) {
if (msgOk) { msgOk.textContent = ''; setHidden(msgOk, true) }
if (msgErr) { msgErr.innerHTML = html || ''; setHidden(msgErr, !html) }
}
var titleField = document.createElement('div')
titleField.className = 'ps-news-modal__field'
var titleLabel = document.createElement('div')
titleLabel.className = 'ps-news-modal__label'
titleLabel.textContent = 'Заголовок'
var titleInput = document.createElement('input')
titleInput.type = 'text'
titleInput.className = 'ps-news-modal__input'
titleInput.value = editItem && editItem.title ? String(editItem.title) : ''
titleField.appendChild(titleLabel)
titleField.appendChild(titleInput)
var importantBox = document.createElement('div')
importantBox.className = 'checkbox'
var importantId = 'news_important_' + String((new Date()).getTime())
var importantInput = document.createElement('input')
importantInput.name = 'is_important'
importantInput.id = importantId
importantInput.type = 'checkbox'
importantInput.value = '1'
if (editItem && parseInt(editItem.is_important, 10) === 1) {
importantInput.checked = true
}
var importantLabel = document.createElement('label')
importantLabel.className = 'label'
importantLabel.setAttribute('for', importantId)
importantLabel.textContent = 'Важная новость'
importantBox.appendChild(importantInput)
importantBox.appendChild(importantLabel)
var editorId = 'ps_news_body_' + String((new Date()).getTime())
var textLabel = document.createElement('div')
textLabel.className = 'ps-news-modal__label'
textLabel.textContent = 'Текст новости'
var textarea = document.createElement('textarea')
textarea.className = 'ps-news-modal__textarea'
textarea.id = editorId
textarea.value = editItem && editItem.body_html ? String(editItem.body_html) : ''
bodyEl.appendChild(msgOk)
bodyEl.appendChild(msgErr)
bodyEl.appendChild(titleField)
bodyEl.appendChild(importantBox)
bodyEl.appendChild(textLabel)
bodyEl.appendChild(textarea)
var actionsEl = document.createElement('div')
actionsEl.className = 'ps-news-modal__actions'
var cancelBtn = document.createElement('button')
cancelBtn.type = 'button'
cancelBtn.className = 'partner-settings-btn'
cancelBtn.textContent = 'Отмена'
var saveBtn = document.createElement('button')
saveBtn.type = 'button'
saveBtn.className = 'ps-mat2__create'
saveBtn.textContent = isEdit ? 'Сохранить изменения' : 'Сохранить'
actionsEl.appendChild(cancelBtn)
actionsEl.appendChild(saveBtn)
boxEl.appendChild(headerEl)
boxEl.appendChild(bodyEl)
boxEl.appendChild(actionsEl)
overlayEl.appendChild(boxEl)
document.body.appendChild(overlayEl)
var editor = null
function closeModal() {
if (editor) {
try { editor.destroy(true) } catch (e) {}
editor = null
}
if (overlayEl && overlayEl.parentNode) overlayEl.parentNode.removeChild(overlayEl)
}
closeBtn.addEventListener('click', closeModal)
cancelBtn.addEventListener('click', closeModal)
ensureCkEditor(function (ok) {
if (!ok) {
modalShowErr('Не удалось загрузить редактор')
return
}
editor = window.CKEDITOR.replace(editorId, {
height: 320,
resize_enabled: false,
removePlugins: 'elementspath,uploadimage,uploadwidget,uploadfile,filetools,exportpdf',
removeDialogTabs: 'link:upload;image:Upload;image2:Upload',
toolbar: [
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike', 'RemoveFormat'] },
{ name: 'paragraph', items: ['Format', 'NumberedList', 'BulletedList', 'Outdent', 'Indent', 'Blockquote'] },
{ name: 'links', items: ['Link', 'Unlink'] },
{ name: 'insert', items: ['Table', 'HorizontalRule', 'Smiley', 'SpecialChar'] },
{ name: 'document', items: ['Source'] }
]
})
editor.on('instanceReady', function () {
if (editItem && editItem.body_html) {
try { editor.setData(String(editItem.body_html)) } catch (e) {}
}
})
})
saveBtn.addEventListener('click', function () {
modalShowOk('')
modalShowErr('')
var title = String(titleInput.value || '').trim()
if (!title) {
modalShowErr('Введите заголовок')
return
}
var html = ''
if (editor) html = editor.getData()
else html = String(textarea.value || '')
var importantVal = (importantInput && importantInput.checked) ? '1' : '0'
var fd = new FormData()
fd.append('action', isEdit ? 'news_update' : 'news_create')
if (isEdit) fd.append('news_id', String(editItem.id))
fd.append('title', title)
fd.append('body_html', html)
fd.append('is_important', importantVal)
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
modalShowErr(msg)
return
}
closeModal()
if (onSaved) onSaved()
showOk(root, isEdit ? 'Новость успешно обновлена' : 'Новость успешно создана')
})
})
setTimeout(function () {
try { titleInput.focus() } catch (e) {}
}, 50)
}
function openConfirmModal(opts) {
opts = opts || {}
var title = String(opts.title || 'Подтверждение')
var text = String(opts.text || 'Вы уверены?')
var okText = String(opts.okText || 'Удалить')
var cancelText = String(opts.cancelText || 'Отмена')
var onConfirm = typeof opts.onConfirm === 'function' ? opts.onConfirm : function () {}
// чтобы не открыть две сразу
if (qs('.ps-confirm-modal')) return
var overlay = document.createElement('div')
overlay.className = 'ps-confirm-modal'
var box = document.createElement('div')
box.className = 'ps-confirm-modal__box'
var head = document.createElement('div')
head.className = 'ps-confirm-modal__head'
var titleEl = document.createElement('div')
titleEl.className = 'ps-confirm-modal__title'
titleEl.textContent = title
var closeBtn = document.createElement('button')
closeBtn.type = 'button'
closeBtn.className = 'ps-confirm-modal__close'
closeBtn.textContent = '×'
head.appendChild(titleEl)
head.appendChild(closeBtn)
var body = document.createElement('div')
body.className = 'ps-confirm-modal__body'
body.textContent = text
var actions = document.createElement('div')
actions.className = 'ps-confirm-modal__actions'
var cancelBtn = document.createElement('button')
cancelBtn.type = 'button'
cancelBtn.className = 'partner-settings-btn'
cancelBtn.textContent = cancelText
var okBtn = document.createElement('button')
okBtn.type = 'button'
okBtn.className = 'ps-confirm-modal__danger'
okBtn.textContent = okText
actions.appendChild(cancelBtn)
actions.appendChild(okBtn)
box.appendChild(head)
box.appendChild(body)
box.appendChild(actions)
overlay.appendChild(box)
document.body.appendChild(overlay)
function closeModal() {
if (overlay && overlay.parentNode) overlay.parentNode.removeChild(overlay)
document.removeEventListener('keydown', onKeyDown, true)
}
function onKeyDown(e) {
if (e.keyCode === 27) {
e.preventDefault()
closeModal()
}
if (e.keyCode === 13) {
e.preventDefault()
closeModal()
onConfirm()
}
}
closeBtn.addEventListener('click', closeModal)
cancelBtn.addEventListener('click', closeModal)
okBtn.addEventListener('click', function () {
closeModal()
onConfirm()
})
overlay.addEventListener('click', function (e) {
if (e.target === overlay) closeModal()
})
document.addEventListener('keydown', onKeyDown, true)
setTimeout(function () {
try { okBtn.focus() } catch (e) {}
}, 20)
}
function bindNews(root) {
var listBox = qs('[data-ps-news-list]', root)
var empty = qs('[data-ps-news-empty]', root)
var addBtn = qs('[data-ps-news-add]', root)
if (!listBox) return
var state = {
items: [],
loaded: false,
openId: 0
}
function setEmptyVisible(v) {
if (!empty) return
if (v) empty.style.display = 'block'
if (!v) empty.style.display = 'none'
}
function render() {
listBox.innerHTML = ''
if (!state.items.length) setEmptyVisible(true)
if (state.items.length) setEmptyVisible(false)
var i = 0
while (i < state.items.length) {
var it = state.items[i]
var item = document.createElement('div')
item.className = 'ps-news__item'
var row = document.createElement('div')
row.className = 'ps-news__row'
var name = document.createElement('div')
name.className = 'ps-news__name'
name.innerHTML = ''
if (it.is_important && parseInt(it.is_important, 10) === 1) {
var badge = document.createElement('span')
badge.className = 'ps-news__badge'
badge.textContent = 'ВАЖНО'
name.appendChild(badge)
}
var titleSpan = document.createElement('span')
titleSpan.textContent = it.title || ''
name.appendChild(titleSpan)
var meta = document.createElement('div')
meta.className = 'ps-news__meta'
meta.textContent = it.created_at || ''
var actions = document.createElement('div')
actions.className = 'ps-news__actions'
var edit = document.createElement('button')
edit.type = 'button'
edit.className = 'ps-mat2__icon'
edit.setAttribute('data-news-edit', String(it.id))
edit.innerHTML = svgEdit15()
var del = document.createElement('button')
del.type = 'button'
del.className = 'ps-mat2__icon ps-mat2__icon--danger'
del.setAttribute('data-news-del', String(it.id))
del.innerHTML = svgTrash18()
var op = document.createElement('button')
op.type = 'button'
op.className = 'ps-mat2__icon'
op.setAttribute('data-news-open', String(it.id))
if (state.openId === it.id) op.textContent = '-'
if (state.openId !== it.id) op.textContent = '+'
actions.appendChild(edit)
actions.appendChild(del)
actions.appendChild(op)
row.appendChild(name)
row.appendChild(meta)
row.appendChild(actions)
item.appendChild(row)
if (state.openId === it.id) {
var body = document.createElement('div')
body.className = 'ps-news__body'
body.innerHTML = it.body_html || ''
item.appendChild(body)
}
listBox.appendChild(item)
i++
}
}
function load() {
var fd = new FormData()
fd.append('action', 'news_list')
apiPost(fd, function (data) {
if (!data || !data.ok) return
state.items = data.items || []
var keep = false
if (state.openId) {
var i = 0
while (i < state.items.length) {
if (state.items[i].id === state.openId) { keep = true; i = state.items.length; continue }
i++
}
}
if (!keep) state.openId = 0
state.loaded = true
render()
})
}
function deleteNews(newsId) {
showOk(root, '')
showErr(root, '')
var fd = new FormData()
fd.append('action', 'news_delete')
fd.append('news_id', String(newsId))
apiPost(fd, function (data) {
if (!data || !data.ok) {
var msg = 'Ошибка'
if (data && data.error) msg = data.error
showErr(root, msg)
return
}
if (state.openId === newsId) state.openId = 0
state.loaded = false
load()
})
}
window.partnerSettingsNewsLoad = function () {
if (!state.loaded) load()
}
if (addBtn) {
addBtn.addEventListener('click', function () {
openNewsCreateModal(root, function () {
state.loaded = false
load()
})
})
}
listBox.addEventListener('click', function (e) {
var t = e.target
var btn = t
while (
btn &&
btn !== listBox &&
!btn.getAttribute('data-news-open') &&
!btn.getAttribute('data-news-del') &&
!btn.getAttribute('data-news-edit')
) {
btn = btn.parentNode
}
if (!btn || btn === listBox) return
var v
v = btn.getAttribute('data-news-open')
if (v) {
var idOpen = parseInt(v, 10)
if (!idOpen) return
if (state.openId === idOpen) {
state.openId = 0
} else {
state.openId = idOpen
}
render()
return
}
v = btn.getAttribute('data-news-edit')
if (v) {
var idEdit = parseInt(v, 10)
if (!idEdit) return
var editItem = null
var k = 0
while (k < state.items.length) {
if (parseInt(state.items[k].id, 10) === idEdit) {
editItem = state.items[k]
break
}
k++
}
if (!editItem) return
openNewsCreateModal(root, function () {
state.loaded = false
load()
}, editItem)
return
}
v = btn.getAttribute('data-news-del')
if (v) {
var idDel = parseInt(v, 10)
if (!idDel) return
openConfirmModal({
title: 'Удаление новости',
text: 'Вы действительно хотите удалить эту новость?',
okText: 'Удалить',
cancelText: 'Отмена',
onConfirm: function () {
deleteNews(idDel)
}
})
return
}
})
}
function bindModal(root) {
bindClose(root)
bindUrlRow(root)
bindMaterials(root)
bindNews(root)
bindTabs(root)
bindBottomSave(root)
}
window.partnerSettingsModalBind = function () {
var root = qs('#partnerSettingsRoot')
if (root) bindModal(root)
}
// function openModal() {
// if (qs('#partnerSettingsRoot')) return
//
// var prevOverflow = document.documentElement.style.overflow
// var prevBodyOverflow = document.body.style.overflow
//
// document.documentElement.style.overflow = 'hidden'
// document.body.style.overflow = 'hidden'
//
// function restoreOverflow() {
// document.documentElement.style.overflow = prevOverflow
// document.body.style.overflow = prevBodyOverflow
// }
//
// var xhr = new XMLHttpRequest()
// xhr.open('GET', MODAL_URL, true)
// xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
// xhr.onreadystatechange = function () {
// if (xhr.readyState !== 4) return
//
// if (xhr.status !== 200) {
// restoreOverflow()
// return
// }
//
// var wrap = document.createElement('div')
// wrap.innerHTML = xhr.responseText
// while (wrap.firstChild) document.body.appendChild(wrap.firstChild)
//
// var root = qs('#partnerSettingsRoot')
// if (root) {
// root._ps_restoreOverflow = restoreOverflow
// } else {
// restoreOverflow()
// }
//
// if (window.partnerSettingsModalBind) window.partnerSettingsModalBind()
// }
// xhr.send(null)
// }
// function bindOpenBtn() {
// var btn = qs('.partners-settings')
// if (!btn) return
// btn.addEventListener('click', openModal)
// }
//
// if (document.readyState === 'loading') {
// document.addEventListener('DOMContentLoaded', bindOpenBtn)
// } else {
// bindOpenBtn()
// }
window.openPartnerSettingsModal = function() {
if (document.getElementById('partnerSettingsRoot')) {
return;
}
var prevOverflow = document.documentElement.style.overflow;
var prevBodyOverflow = document.body.style.overflow;
document.documentElement.style.overflow = 'hidden';
document.body.style.overflow = 'hidden';
function restoreOverflow() {
document.documentElement.style.overflow = prevOverflow;
document.body.style.overflow = prevBodyOverflow;
}
var xhr = new XMLHttpRequest();
xhr.open('GET', MODAL_URL, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.status !== 200) {
restoreOverflow();
return;
}
var wrap = document.createElement('div');
wrap.innerHTML = xhr.responseText;
while (wrap.firstChild) document.body.appendChild(wrap.firstChild);
var root = qs('#partnerSettingsRoot');
if (root) {
root._ps_restoreOverflow = restoreOverflow;
} else {
restoreOverflow();
}
if (window.partnerSettingsModalBind) window.partnerSettingsModalBind();
};
xhr.send(null);
};
})()