MediaWiki:Common.js: Perbedaan antara revisi
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
Tidak ada ringkasan suntingan Tanda: Suntingan perangkat seluler Suntingan peramban seluler |
||
| Baris 1: | Baris 1: | ||
/** | /** | ||
* ==================================================================== | * ==================================================================== | ||
* MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM ( | * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V4.0 ULTIMATE) | ||
* Fitur: | * Fitur: Mobile Responsive, Smart Cache Bypass, Custom Modal, Fix Refs | ||
* ==================================================================== | * ==================================================================== | ||
*/ | */ | ||
| Baris 8: | Baris 8: | ||
'use strict'; | 'use strict'; | ||
// 1. CEK LINGKUNGAN | // 1. CEK LINGKUNGAN | ||
if (mw.config.get('wgNamespaceNumber') !== 0 || mw.config.get('wgIsMainPage')) { | if (mw.config.get('wgNamespaceNumber') !== 0 || mw.config.get('wgIsMainPage')) { | ||
return; | return; | ||
| Baris 29: | Baris 29: | ||
var svgLock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>'; | var svgLock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>'; | ||
var svgUnlock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>'; | var svgUnlock = '<svg class="md-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>'; | ||
var svgRef = '<svg class="md-icon" width=" | var svgRef = '<svg class="md-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'; | ||
var | var svgInfo = '<svg class="md-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#d32f2f" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>'; | ||
// 3. INJEKSI CSS TAMPILAN | // 3. INJEKSI CSS TAMPILAN (DIPERBARUI UNTUK MOBILE) | ||
var css = ` | var css = ` | ||
#mippedia-data-app { | #mippedia-data-app { | ||
background: #ffffff; | background: #ffffff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.05); | ||
padding: 24px; margin: 24px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; | |||
border: 1px solid #eaeaea; transition: all 0.3s ease; | |||
padding: 24px; | |||
border: 1px solid # | |||
} | } | ||
.md-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #f0f0f0; } | .md-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #f0f0f0; } | ||
| Baris 51: | Baris 46: | ||
.md-btn-icon { | .md-btn-icon { | ||
background: #f8f9fa; border: 1px solid #e2e2e2; cursor: pointer; color: #5a42b8; | background: #f8f9fa; border: 1px solid #e2e2e2; cursor: pointer; color: #5a42b8; | ||
padding: 7px | padding: 7px 14px; border-radius: 8px; transition: all 0.2s ease; | ||
display: inline-flex; align-items: center; gap: 6px; font-size: 0.85em; font-weight: 600; | display: inline-flex; align-items: center; gap: 6px; font-size: 0.85em; font-weight: 600; | ||
} | } | ||
.md-btn-icon:hover:not(:disabled) { background: #eef2f5; border-color: #d0d0d0 | .md-btn-icon:hover:not(:disabled) { background: #eef2f5; border-color: #d0d0d0; } | ||
.md-btn-lock { color: #d32f2f; background: #fff5f5; border-color: #fbd6d6; } | .md-btn-lock { color: #d32f2f; background: #fff5f5; border-color: #fbd6d6; } | ||
.md-btn-lock:hover:not(:disabled) { background: #fee2e2; } | .md-btn-lock:hover:not(:disabled) { background: #fee2e2; } | ||
.md- | |||
.md- | /* Badge Terkunci untuk Anon */ | ||
.md-badge-locked { | |||
color: #d32f2f; font-size: 0.9em; font-weight: bold; background: #fff5f5; | |||
padding: 7px 12px; border-radius: 8px; border: 1px solid #fbd6d6; | |||
cursor: pointer; display: inline-flex; align-items: center; gap: 6px; transition: 0.2s; | |||
} | |||
.md-badge-locked:hover { background: #fee2e2; transform: scale(1.02); } | |||
.md-row-display { | .md-row-display { | ||
display: flex; justify-content: space-between; align-items: flex-start; | display: flex; justify-content: space-between; align-items: flex-start; | ||
padding: | padding: 16px 12px; border-bottom: 1px solid #f5f5f5; transition: background 0.2s; border-radius: 8px; gap: 15px; | ||
} | } | ||
.md-row-display:hover { background: #fafafa; } | .md-row-display:hover { background: #fafafa; box-shadow: inset 4px 0 0 #5a42b8; } | ||
.md-row-display:last-child { border-bottom: none; } | .md-row-display:last-child { border-bottom: none; } | ||
.md-data-group { display: flex; flex-direction: column; gap: | .md-data-group { display: flex; flex-direction: column; gap: 4px; flex: 1; } | ||
.md-data-label { font-size: 0. | .md-data-label { font-size: 0.75em; color: #666; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; } | ||
.md-data-value { font-size: 1.05em; color: #202124; line-height: 1.4; } | .md-data-value { font-size: 1.05em; color: #202124; line-height: 1.4; font-weight: 500; } | ||
.md-ref- | /* Desain Referensi Baru (Elegan & Nyata) */ | ||
.md-ref-container { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; background: #f8f9fa; padding: 10px 12px; border-radius: 8px; border-left: 3px solid #1a73e8; } | |||
.md-ref-link { font-size: 0.85em; font-weight: 600; color: #1a73e8; text-decoration: none; display: inline-flex; align-items: center; gap: 5px; } | |||
.md-ref-link:hover { text-decoration: underline; } | |||
.md-ref-meta { font-size: 0.75em; color: #5f6368; line-height: 1.5; } | |||
.md-ref- | |||
/* Form Edit | /* Form Edit */ | ||
.md-form-box { background: #fafbfc; border-radius: | .md-form-box { background: #fafbfc; border-radius: 12px; padding: 24px; margin-top: 20px; border: 1px solid #eaedf0; box-shadow: 0 4px 15px rgba(0,0,0,0.03); } | ||
.md-form-title { font-size: 1em; font-weight: | .md-form-title { font-size: 1.1em; font-weight: 700; color: #333; margin: 0 0 20px 0; border-bottom: 2px solid #e2e2e2; padding-bottom: 8px; } | ||
.md-form-group { margin-bottom: | .md-form-group { margin-bottom: 18px; } | ||
.md-form-group label { display: block; font-size: 0.85em; font-weight: 600; margin-bottom: | .md-form-group label { display: block; font-size: 0.85em; font-weight: 600; margin-bottom: 8px; color: #444; } | ||
.md-input, .md-select { | .md-input, .md-select { | ||
width: 100%; padding: | width: 100%; padding: 12px 14px; border: 1px solid #ccc; border-radius: 8px; | ||
box-sizing: border-box; font-family: inherit; font-size: 0.95em; transition: | box-sizing: border-box; font-family: inherit; font-size: 0.95em; transition: 0.2s; background: #fff; | ||
} | } | ||
.md-input:focus, .md-select:focus { border-color: #5a42b8; outline: none; box-shadow: 0 0 0 3px rgba(90, 66, 184, 0. | .md-input:focus, .md-select:focus { border-color: #5a42b8; outline: none; box-shadow: 0 0 0 3px rgba(90, 66, 184, 0.15); } | ||
.md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; background: #fff; padding: 18px; border-radius: 8px; border: 1px dashed #bbb; } | |||
.md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; background: #fff; padding: | |||
.md-grid-full { grid-column: span 2; } | .md-grid-full { grid-column: span 2; } | ||
.md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: 25px; padding-top: 15px; border-top: 1px solid #eaeaea; } | |||
.md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: | |||
.md-btn { | .md-btn { | ||
padding: | padding: 12px 24px; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; | ||
color: white; font-size: 0.9em; transition: | color: white; font-size: 0.9em; transition: 0.2s; display: inline-flex; align-items: center; gap: 8px; justify-content: center; | ||
} | } | ||
.md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px | .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); } | ||
.md-btn:disabled { opacity: 0.6; cursor: not-allowed; } | .md-btn:disabled { opacity: 0.6; cursor: not-allowed; } | ||
.md-btn-save { background: linear-gradient(135deg, #6b52d1, #5a42b8); } | .md-btn-save { background: linear-gradient(135deg, #6b52d1, #5a42b8); } | ||
| Baris 106: | Baris 103: | ||
.md-btn-delete { background: linear-gradient(135deg, #e53935, #c62828); margin-left: auto; } | .md-btn-delete { background: linear-gradient(135deg, #e53935, #c62828); margin-left: auto; } | ||
.md-spinner { | .md-spinner { display: none; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.4); border-radius: 50%; border-top-color: #fff; animation: md-spin 0.8s linear infinite; } | ||
.md-btn-icon .md-spinner { border-color: rgba(0,0,0,0.2); border-top-color: currentColor; } | .md-btn-icon .md-spinner { border-color: rgba(0,0,0,0.2); border-top-color: currentColor; } | ||
.is-loading .md-spinner { display: inline-block; } | .is-loading .md-spinner { display: inline-block; } | ||
@keyframes md-spin { to { transform: rotate(360deg); } } | @keyframes md-spin { to { transform: rotate(360deg); } } | ||
/* Custom Modal Alert */ | |||
.md-overlay { | |||
position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.5); backdrop-filter: blur(3px); | |||
z-index: 9999; display: flex; justify-content: center; align-items: center; opacity: 0; visibility: hidden; transition: 0.3s; | |||
} | |||
.md-overlay.md-show { opacity: 1; visibility: visible; } | |||
.md-modal { | |||
background: #fff; padding: 25px; border-radius: 16px; width: 90%; max-width: 400px; | |||
text-align: center; box-shadow: 0 10px 40px rgba(0,0,0,0.2); transform: translateY(20px); transition: 0.3s; | |||
} | |||
.md-overlay.md-show .md-modal { transform: translateY(0); } | |||
.md-modal-title { font-size: 1.2em; font-weight: 700; color: #333; margin: 15px 0 10px; } | |||
.md-modal-text { font-size: 0.95em; color: #555; line-height: 1.5; margin-bottom: 20px; } | |||
.md-btn-close-modal { background: #5a42b8; color: #fff; padding: 10px 20px; border: none; border-radius: 8px; font-weight: 600; cursor: pointer; width: 100%; transition: 0.2s;} | |||
.md-btn-close-modal:hover { background: #48349c; } | |||
/* MEDIA QUERY UNTUK HP (MOBILE RESPONSIVE) */ | |||
@media (max-width: 600px) { | |||
#mippedia-data-app { padding: 15px; } | |||
.md-header { flex-direction: column; align-items: flex-start; gap: 15px; } | |||
.md-actions { width: 100%; justify-content: space-between; } | |||
.md-row-display { flex-direction: column; position: relative; padding-bottom: 20px; } | |||
.md-btn-icon.edit-btn { position: absolute; top: 10px; right: 10px; padding: 5px 10px; } | |||
.md-ref-grid { grid-template-columns: 1fr; gap: 10px; padding: 12px; } | |||
.md-grid-full { grid-column: span 1; } | |||
.md-form-actions { flex-direction: column; width: 100%; } | |||
.md-btn { width: 100%; margin: 0 !important; } | |||
} | |||
.md-native-render { display: none; } | .md-native-render { display: none; } | ||
`; | `; | ||
$('<style>').text(css).appendTo('head'); | $('<style>').text(css).appendTo('head'); | ||
// 4. PARSER DATA | // 4. SISTEM MODAL NOTIFIKASI | ||
function showModal(title, text) { | |||
var $overlay = $('<div class="md-overlay"></div>'); | |||
var $modal = $('<div class="md-modal"></div>'); | |||
$modal.append(svgInfo); | |||
$modal.append('<div class="md-modal-title">' + title + '</div>'); | |||
$modal.append('<div class="md-modal-text">' + text + '</div>'); | |||
var $btn = $('<button class="md-btn-close-modal">Saya Mengerti</button>'); | |||
$btn.on('click', function() { $overlay.removeClass('md-show'); setTimeout(function(){ $overlay.remove(); }, 300); }); | |||
$modal.append($btn); | |||
$overlay.append($modal); | |||
$('body').append($overlay); | |||
// Trigger animasi | |||
setTimeout(function() { $overlay.addClass('md-show'); }, 10); | |||
} | |||
// 5. PARSER DATA | |||
function loadData() { | function loadData() { | ||
return api.get({ | return api.get({ | ||
| Baris 137: | Baris 177: | ||
} | } | ||
// --- HELPER UNTUK MEMBENTUK TEKS REFERENSI --- | // --- HELPER UNTUK MEMBENTUK TEKS REFERENSI (WIKITEXT) --- | ||
function buildWikitextRef(refObj) { | function buildWikitextRef(refObj) { | ||
if (!refObj) return ""; | if (!refObj) return ""; | ||
if (typeof refObj === 'string') return refObj ? "[ " + refObj + " Rujukan]" : ""; | if (typeof refObj === 'string') return refObj ? "[ " + refObj + " Rujukan]" : ""; | ||
var text = ""; | |||
var title = refObj.title || "Tautan Rujukan"; | |||
if (refObj.url) { | |||
text = "[" + refObj.url + " " + title + "]"; | |||
} else if (refObj.title) { | |||
text = "'''" + refObj.title + "'''"; | |||
} else { | |||
text = "Sumber Rujukan"; | |||
} | |||
var details = []; | var details = []; | ||
| Baris 151: | Baris 197: | ||
if (refObj.site) details.push("Situs: " + refObj.site); | if (refObj.site) details.push("Situs: " + refObj.site); | ||
if (refObj.publisher) details.push("Penerbit: " + refObj.publisher); | if (refObj.publisher) details.push("Penerbit: " + refObj.publisher); | ||
if (refObj.date) details.push("Diakses | if (refObj.date) details.push("Diakses: " + refObj.date); | ||
if (refObj.type) details.push("Format: " + refObj.type); | if (refObj.type) details.push("Format: " + refObj.type); | ||
| Baris 160: | Baris 206: | ||
} | } | ||
// | // 6. PENYIMPANAN KE WIKITEXT API | ||
function saveData(actionType, $btnEl, originalContent) { | function saveData(actionType, $btnEl, originalContent) { | ||
if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true); | if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true); | ||
| Baris 185: | Baris 231: | ||
// SIMPAN DATA | // SIMPAN DATA | ||
api.postWithToken('csrf', { | api.postWithToken('csrf', { | ||
action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data: ' + actionType, minor: | action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data: ' + actionType, minor: false // minor=false trigger cache lebih baik | ||
}).done(function() { | }).done(function() { | ||
// | // BYPASS CACHE CERDAS: Gunakan parameter waktu untuk maksa server merefresh file html tanpa halaman konfirmasi "Purge" | ||
var nocacheUrl = location.pathname + "?update=" + new Date().getTime(); | |||
window.location.href = nocacheUrl; | |||
}).fail(function(err) { | }).fail(function(err) { | ||
if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false); | if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false); | ||
alert("Gagal menyimpan! (Error: " + err + ") | alert("Gagal menyimpan! (Error: " + err + ")."); | ||
}); | }); | ||
} | } | ||
// | // 7. BUILDER UI UTAMA | ||
function buildUI(rawContent) { | function buildUI(rawContent) { | ||
var $app = $('<div id="mippedia-data-app"></div>'); | var $app = $('<div id="mippedia-data-app"></div>'); | ||
var $header = $('<div class="md-header"><h3 class="md-title">' + svgEdit + ' Mippedia Data | var $header = $('<div class="md-header"><h3 class="md-title">' + svgEdit + ' Mippedia Data</h3></div>'); | ||
var $actions = $('<div class="md-actions"></div>'); | var $actions = $('<div class="md-actions"></div>'); | ||
| Baris 208: | Baris 253: | ||
var lockClass = isLocked ? 'md-btn-unlock' : 'md-btn-lock'; | var lockClass = isLocked ? 'md-btn-unlock' : 'md-btn-lock'; | ||
var $lockBtn = $('<button class="md-btn-icon ' + lockClass + '">' + lockIcon + lockText + ' <span class="md-spinner"></span></button>'); | |||
var $lockBtn = $('<button class="md-btn-icon ' + lockClass + ' | |||
$lockBtn.on('click', function() { | $lockBtn.on('click', function() { | ||
isLocked = !isLocked; | isLocked = !isLocked; | ||
| Baris 216: | Baris 260: | ||
$actions.append($lockBtn); | $actions.append($lockBtn); | ||
} else if (isLocked) { | } else if (isLocked) { | ||
$ | var $lockedBadge = $('<span class="md-badge-locked">' + svgLock + ' Terkunci</span>'); | ||
$lockedBadge.on('click', function() { | |||
showModal('Halaman Terkunci', 'Data terstruktur pada halaman ini telah dikunci oleh Pengurus untuk menjaga keakuratan dan integritas informasi. Anda tidak dapat melakukan perubahan saat ini.'); | |||
}); | |||
$actions.append($lockedBadge); | |||
} | } | ||
| Baris 237: | Baris 285: | ||
$info.append('<span class="md-data-label">' + item.prop + '</span>'); | $info.append('<span class="md-data-label">' + item.prop + '</span>'); | ||
var displayVal = item.link ? '<a href="' + mw.util.getUrl(item.val) + '" style="color:#1a73e8; text-decoration:none; font-weight:600;">' + item.val + '</a>' : item.val; | var displayVal = item.link ? '<a href="' + mw.util.getUrl(item.val) + '" style="color:#1a73e8; text-decoration:none; font-weight:600;">' + item.val + '</a>' : item.val; | ||
$ | $info.append('<span class="md-data-value">' + displayVal + '</span>'); | ||
// | // RENDER REFERENSI DI TAMPILAN NYATA (Bukan Tooltip) | ||
if (item.ref) { | if (item.ref) { | ||
var isObj = typeof item.ref === 'object'; | var isObj = typeof item.ref === 'object'; | ||
var refUrl = isObj ? item.ref.url : item.ref; | var refUrl = isObj ? item.ref.url : item.ref; | ||
var refTitle = (isObj && item.ref.title) ? item.ref.title : " | var refTitle = (isObj && item.ref.title) ? item.ref.title : "Tautan Rujukan"; | ||
var | |||
var $refBox = $('<div class="md-ref-container"></div>'); | |||
// Baris 1: URL atau Judul | |||
if (refUrl) { | |||
$refBox.append('<a href="' + refUrl + '" target="_blank" class="md-ref-link">' + svgRef + refTitle + '</a>'); | |||
} else if (isObj && item.ref.title) { | |||
$refBox.append('<span style="font-weight:600; font-size:0.85em; color:#444;">' + svgRef + item.ref.title + '</span>'); | |||
} | |||
// Baris 2: Detail Metadata (Penulis, Situs, Waktu) | |||
if (isObj) { | if (isObj) { | ||
if(item.ref.author) | var meta = []; | ||
if(item.ref.publisher) | if (item.ref.author) meta.push(item.ref.author); | ||
if(item.ref.date) | if (item.ref.site) meta.push("<i>" + item.ref.site + "</i>"); | ||
if (item.ref.publisher) meta.push(item.ref.publisher); | |||
if (item.ref.date) meta.push(item.ref.date); | |||
if (item.ref.type) meta.push("[" + item.ref.type + "]"); | |||
if (meta.length > 0) { | |||
$refBox.append('<div class="md-ref-meta">' + meta.join(" • ") + '</div>'); | |||
} | |||
} | } | ||
$info.append($refBox); | |||
} | } | ||
$row.append($info); | $row.append($info); | ||
if (!isLocked || isSysop) { | if (!isLocked || isSysop) { | ||
var $editIcon = $('<button class="md-btn-icon | var $editIcon = $('<button class="md-btn-icon edit-btn">' + svgEdit + ' Edit</button>'); | ||
$editIcon.on('click', function() { showForm(index, rawContent); }); | $editIcon.on('click', function() { showForm(index, rawContent); }); | ||
$row.append($editIcon); | $row.append($editIcon); | ||
| Baris 287: | Baris 347: | ||
} | } | ||
// 8. LOGIKA FORM EDIT ( | // 8. LOGIKA FORM EDIT (RESPONSIVE GRID & BUG FIX) | ||
function showForm(index, rawContent) { | function showForm(index, rawContent) { | ||
var $container = $('#md-form-container'); | var $container = $('#md-form-container'); | ||
| Baris 295: | Baris 355: | ||
var currentData = isNew ? { prop: '', val: '', link: false, ref: {} } : dataItems[index]; | var currentData = isNew ? { prop: '', val: '', link: false, ref: {} } : dataItems[index]; | ||
var currentRef = currentData.ref || {}; | var currentRef = currentData.ref || {}; | ||
if (typeof currentRef === 'string') currentRef = { url: currentRef }; | if (typeof currentRef === 'string') currentRef = { url: currentRef }; | ||
var $form = $('<div class="md-form-box"></div>'); | var $form = $('<div class="md-form-box"></div>'); | ||
$form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data') + '</h4>'); | $form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data') + '</h4>'); | ||
$form.append('<div class="md-form-group"><label>Label Data (Contoh: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input" value="' + (currentData.prop || '') + '"></div>'); | $form.append('<div class="md-form-group"><label>Label Data (Contoh: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input" value="' + (currentData.prop || '') + '"></div>'); | ||
$form.append('<div class="md-form-group"><label>Nilai Data</label><input type="text" id="md-inp-val" class="md-input" value="' + (currentData.val || '') + '"></div>'); | $form.append('<div class="md-form-group"><label>Nilai Data</label><input type="text" id="md-inp-val" class="md-input" value="' + (currentData.val || '') + '"></div>'); | ||
var chk = currentData.link ? 'checked' : ''; | var chk = currentData.link ? 'checked' : ''; | ||
$form.append('<label | $form.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.9em; cursor:pointer;"><input type="checkbox" id="md-inp-link" ' + chk + '> Jadikan Tautan Internal (Wikilink)</label>'); | ||
// Grid Detail Referensi | // Grid Detail Referensi | ||
var $refArea = $('<div class="md-form-group" style="margin-top:25px;"></div>'); | var $refArea = $('<div class="md-form-group" style="margin-top:25px;"></div>'); | ||
$refArea.append('<label>Sumber Referensi <span | $refArea.append('<label>Sumber Referensi <span style="color:#888; font-weight:normal; font-size:0.9em;">(Opsional, isi yang diketahui saja)</span></label>'); | ||
var $refGrid = $('<div class="md-ref-grid"></div>'); | var $refGrid = $('<div class="md-ref-grid"></div>'); | ||
$refGrid.append('<div class="md-grid-full"><input type="url" id="md-ref-url" class="md-input" placeholder="URL Tautan (https://...)" value="' + (currentRef.url || '') + '"></div>'); | $refGrid.append('<div class="md-grid-full"><input type="url" id="md-ref-url" class="md-input" placeholder="URL Tautan (https://...)" value="' + (currentRef.url || '') + '"></div>'); | ||
$refGrid.append('<div><input type="text" id="md-ref-title" class="md-input" placeholder="Judul Halaman Web/Buku" value="' + (currentRef.title || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-site" class="md-input" placeholder="Nama Situs (cth: Kompas)" value="' + (currentRef.site || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-title" class="md-input" placeholder="Judul Halaman Web" value="' + (currentRef.title || '') + '"></div>'); | |||
$refGrid.append('<div><input type="text" id="md-ref-site" class="md-input" placeholder="Nama Situs (cth: Kompas | |||
$refGrid.append('<div><input type="text" id="md-ref-publisher" class="md-input" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>'); | $refGrid.append('<div><input type="text" id="md-ref-publisher" class="md-input" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>'); | ||
$refGrid.append('<div><input type="text" id="md-ref-author" class="md-input" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>'); | $refGrid.append('<div><input type="text" id="md-ref-author" class="md-input" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>'); | ||
| Baris 334: | Baris 388: | ||
$form.append($refArea); | $form.append($refArea); | ||
var $actions = $('<div class="md-form-actions"></div>'); | var $actions = $('<div class="md-form-actions"></div>'); | ||
var $btnSave = $('<button class="md-btn md-btn-save">Simpan Data <span class="md-spinner"></span></button>'); | var $btnSave = $('<button class="md-btn md-btn-save">Simpan Data <span class="md-spinner"></span></button>'); | ||
| Baris 355: | Baris 408: | ||
$form.append($actions); | $form.append($actions); | ||
$container.append($form); | $container.append($form); | ||
$('html, body').animate({ scrollTop: $form.offset().top - 80 }, 300); | |||
$('html, body').animate({ scrollTop: $form.offset().top - | |||
$btnCancel.on('click', function() { $container.empty(); }); | $btnCancel.on('click', function() { $container.empty(); }); | ||
| Baris 367: | Baris 417: | ||
if (!newProp || !newVal) { | if (!newProp || !newVal) { | ||
alert("Label Data dan Nilai | alert("Label Data dan Nilai wajib diisi!"); return; | ||
} | } | ||
var refObj = { | var refObj = { | ||
url: $('#md-ref-url').val().trim(), | url: $('#md-ref-url').val().trim(), | ||
| Baris 381: | Baris 430: | ||
}; | }; | ||
// | // BUG FIX: Hapus key yang kosong. Kalo semua kosong, baru jadikan null. | ||
Object.keys(refObj).forEach(key => { if (!refObj[key]) delete refObj[key]; }); | Object.keys(refObj).forEach(key => { if (!refObj[key]) delete refObj[key]; }); | ||
if (Object.keys(refObj).length === 0) { | |||
refObj = null; | |||
if ( | } | ||
var newItem = { prop: newProp, val: newVal, link: newLink, ref: refObj }; | var newItem = { prop: newProp, val: newVal, link: newLink, ref: refObj }; | ||
if (isNew) dataItems.push(newItem); | if (isNew) dataItems.push(newItem); | ||
else dataItems[index] = newItem; | else dataItems[index] = newItem; | ||
| Baris 396: | Baris 444: | ||
} | } | ||
// 9. | // 9. EKSEKUSI UTAMA | ||
loadData().then(function(rawContent) { buildUI(rawContent); }); | loadData().then(function(rawContent) { buildUI(rawContent); }); | ||
}); | }); | ||