644 lines
22 KiB
JavaScript
644 lines
22 KiB
JavaScript
class LayoutManager {
|
|
constructor(container, layoutData) {
|
|
this.rootContainer = container;
|
|
this.tempContainer = null;
|
|
this.editContainerIndex = -1;
|
|
this.layoutData = layoutData || {
|
|
type: 'root',
|
|
styles: {
|
|
'display': 'flex',
|
|
'flex-direction': 'column',
|
|
'justify-content': 'start',
|
|
'align-items': 'flex-start',
|
|
'gap': '10px',
|
|
'width': '100%',
|
|
'height': '100vh',
|
|
'position': 'relative',
|
|
'overflow': 'auto',
|
|
'background-color': '#100C2A'
|
|
},
|
|
children: []
|
|
};
|
|
|
|
this.containerEditorModel = [
|
|
{
|
|
'groupName': 'default',
|
|
'groupTitle': '기본',
|
|
'fields': [
|
|
{
|
|
'path': 'styles.display',
|
|
'type': 'select',
|
|
'label': 'Display',
|
|
'options': ['flex']
|
|
},
|
|
{
|
|
'path': 'styles.flex-direction',
|
|
'type': 'select',
|
|
'label': 'Flex 방향',
|
|
'options': ['row', 'column', 'row-reverse', 'column-reverse']
|
|
},
|
|
{
|
|
'path': 'styles.width',
|
|
'type': 'text',
|
|
'label': '길이(px, %)',
|
|
'placeholder': 'px, % 등 단위를 포함한 길이를 입력하세요'
|
|
},
|
|
{
|
|
'path': 'styles.height',
|
|
'type': 'text',
|
|
'label': '높이(px, %)',
|
|
'placeholder': 'px, % 등 단위를 포함한 높이를 입력하세요'
|
|
}
|
|
]
|
|
}
|
|
];
|
|
|
|
this.dashboardEditorModel = [
|
|
{
|
|
'groupName': 'default',
|
|
'groupTitle': '기본',
|
|
'fields': [
|
|
{
|
|
'path': 'styles.background-color',
|
|
'type': 'text',
|
|
'label': '색상',
|
|
'placeholder': '#로 시작하는 값을 입력하세요'
|
|
},
|
|
{
|
|
'path': 'styles.width',
|
|
'type': 'text',
|
|
'label': '길이(px)',
|
|
'placeholder': 'px 단위를 포함한 길이를 입력하세요'
|
|
},
|
|
{
|
|
'path': 'styles.height',
|
|
'type': 'text',
|
|
'label': '높이(px)',
|
|
'placeholder': 'px 단위를 포함한 높이를 입력하세요'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
|
|
}
|
|
|
|
// traverse(obj) {
|
|
// if (obj.type === 'chart') {
|
|
// $(`#chart_${obj.contentId}`).closest('.dashboard-chart').resizable({
|
|
// grid: 10,
|
|
// ghost: true,
|
|
// stop: (event, ui) => {
|
|
// const {width, height} = ui.size;
|
|
// obj.styles.width = `${width}px`;
|
|
// obj.styles.height = `${height}px`;
|
|
// this.resetLayout();
|
|
// }
|
|
// });
|
|
// }
|
|
//
|
|
// if (obj.children) {
|
|
// obj.children.forEach(child => {
|
|
// this.traverse(child);
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
init(Dashboard, viewerMode) {
|
|
this.viewMode = viewerMode || false;
|
|
this.renderRoot(this.layoutData, this.rootContainer);
|
|
|
|
if (Dashboard) {
|
|
this.dashboard = new Dashboard(this.layoutData);
|
|
this.dashboard.init('chart_area');
|
|
}
|
|
|
|
if (!this.viewMode) {
|
|
this.initContainerEditor();
|
|
this.initDashboardEditor();
|
|
this.chartEditor = new ChartEditor(this.rootContainer, this, this.dashboard);
|
|
this.chartEditor.initChartEditor();
|
|
this.bindEvents();
|
|
}
|
|
}
|
|
|
|
initContainerEditor() {
|
|
const containerEditorPopup = `
|
|
<div class="modal fade" id="container_editor_modal" tabindex="-1" aria-labelledby="container_editor_modal" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">컨테이너 정보</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="containerOption">
|
|
${LayoutUtil.createForm(this.containerEditorModel)}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary btn-sm" data-bs-dismiss="modal">닫기</button>
|
|
<button type="button" class="btn btn-primary btn-sm add-container">추가</button>
|
|
<button type="button" class="btn btn-primary btn-sm save-container">저장</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
$(this.rootContainer).parent().append(containerEditorPopup);
|
|
}
|
|
|
|
initDashboardEditor() {
|
|
const containerEditorPopup = `
|
|
<div class="modal fade" id="dashboard_editor_modal" tabindex="-1" aria-labelledby="dashboard_editor_modal" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">대시보드 정보</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div id="containerOption">
|
|
${LayoutUtil.createForm(this.dashboardEditorModel)}
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary btn-sm" data-bs-dismiss="modal">닫기</button>
|
|
<button type="button" class="btn btn-primary btn-sm save-dashboard">적용</button>
|
|
</div>
|
|
</div>
|
|
`;
|
|
$(this.rootContainer).parent().append(containerEditorPopup);
|
|
}
|
|
|
|
resetLayout() {
|
|
console.log('resetLayout');
|
|
$(this.rootContainer).empty();
|
|
this.renderRoot(this.layoutData, this.rootContainer);
|
|
this.dashboard.initCharts();
|
|
this.dashboard.layoutData = this.layoutData;
|
|
this.dashboard.drawCharts();
|
|
this.editContainerIndex = -1;
|
|
this.bindEvents();
|
|
}
|
|
|
|
addNewChart(containerIndex) {
|
|
this.editContainerIndex = containerIndex;
|
|
let tempChart = {
|
|
'contentId': '',
|
|
'type': 'chart',
|
|
'styles': {
|
|
width: '100%', height: '100%'
|
|
},
|
|
'config': {
|
|
'tooltip': {
|
|
'trigger': 'axis',
|
|
'show': true
|
|
},
|
|
'legend': {
|
|
'show': true
|
|
},
|
|
'grid': {
|
|
'show': true,
|
|
'top': 0,
|
|
'bottom': 0,
|
|
'left': 0,
|
|
'right': 0,
|
|
'containLabel': true
|
|
},
|
|
'title': {},
|
|
'xAxis': {
|
|
'show': true,
|
|
'type': 'category'
|
|
},
|
|
'yAxis': [
|
|
{
|
|
'show': true,
|
|
'name': '',
|
|
'type': 'value',
|
|
'position': 'left'
|
|
}],
|
|
'toolbox': {
|
|
'show': true
|
|
}
|
|
},
|
|
'seriesConfig': [
|
|
{
|
|
'type': 'line',
|
|
'index': '',
|
|
'queryType': 'elasticsearch',
|
|
'query': '',
|
|
'mapperX': `
|
|
function(result) {
|
|
let data = [];
|
|
return data;
|
|
}
|
|
`,
|
|
'mapperY': `
|
|
function(result) {
|
|
let data = [{
|
|
type : 'line',
|
|
data: []
|
|
}];
|
|
return data;
|
|
}
|
|
`,
|
|
'queryResult': ''
|
|
}
|
|
]
|
|
};
|
|
this.chartEditor.showChartEditor(true, tempChart, containerIndex);
|
|
}
|
|
|
|
editChart(editContainerIndex, editColumnIndex) {
|
|
console.log('edit-chart');
|
|
let tempChart = this.layoutData.children[editContainerIndex].children[editColumnIndex];
|
|
this.chartEditor.showChartEditor(false, JSON.parse(JSON.stringify(tempChart, LayoutUtil.echartReplacer)), editContainerIndex, editColumnIndex);
|
|
}
|
|
|
|
renderRoot(layoutData, parent) {
|
|
let classList = 'dashboard-root mt-2' + (!this.viewMode ? ' edit' : '');
|
|
let children = '';
|
|
let style = '';
|
|
if (layoutData.styles) {
|
|
style = Object.keys(layoutData.styles).map(key => `${key}: ${layoutData.styles[key]};`).join(' ');
|
|
}
|
|
console.log({style});
|
|
if (layoutData.children) {
|
|
layoutData.children.forEach((child) => {
|
|
if (child.type === 'container') {
|
|
children += this.renderContainer(child);
|
|
} else if (child.type === 'chart') {
|
|
children += this.renderChart(child);
|
|
}
|
|
});
|
|
}
|
|
let layoutItem = `<div class="${classList}" style="${style}"> ${children}</div>`;
|
|
$(parent).append(layoutItem);
|
|
// if (!this.viewMode) {
|
|
// this.traverse(this.layoutData);
|
|
// }
|
|
};
|
|
|
|
renderChart(layoutData) {
|
|
let style = '';
|
|
if (layoutData.styles) {
|
|
style = Object.keys(layoutData.styles).map(key => `${key}: ${layoutData.styles[key]};`).join(' ');
|
|
}
|
|
|
|
let editButton = this.viewMode ? '' : `<div class="chart-menu-icon" data-content-id="chart_${layoutData.contentId}">
|
|
<div class="dropdown">
|
|
<span class="" data-bs-toggle="dropdown" aria-expanded="false">⋮</span>
|
|
<ul class="dropdown-menu">
|
|
<li><span class="dropdown-item edit-chart">차트 편집</span></li>
|
|
<li><span class="dropdown-item remove-chart">차트 제거</span></li>
|
|
</ul>
|
|
</div>
|
|
</div>`;
|
|
return `
|
|
<div class="dashboard-chart" data-content-id="chart_${layoutData.contentId}" style="${style}">
|
|
${editButton}
|
|
<div id="chart_${layoutData.contentId}" style="width: 100%; height: 100%"></div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
renderContainer(layoutData) {
|
|
console.log('renderContainer');
|
|
|
|
let children = '';
|
|
if (layoutData.children) {
|
|
layoutData.children.forEach(child => {
|
|
if (child.type === 'container') {
|
|
children += this.renderContainer(child);
|
|
} else if (child.type === 'chart') {
|
|
children += this.renderChart(child);
|
|
}
|
|
});
|
|
}
|
|
let width = layoutData.styles.width || '100%';
|
|
let height = layoutData.styles.height || '100%';
|
|
|
|
let editButton = this.viewMode ? '' : `
|
|
<div class="container-menu-icon">
|
|
<div class="dropdown">
|
|
<span><i class="fa-solid fa-arrows-up-down-left-right"></i></span>
|
|
<span class="" data-bs-toggle="dropdown" aria-expanded="false">⋮</span>
|
|
<ul class="dropdown-menu">
|
|
<li><span class="dropdown-item edit-container">컨테이너 편집</span></li>
|
|
<li><span class="dropdown-item remove-container">컨테이너 제거</span></li>
|
|
<li><span class="dropdown-item add-new-chart">차트 추가</span></li>
|
|
</ul>
|
|
</div>
|
|
</div>`;
|
|
|
|
let style = '';
|
|
if (layoutData.styles) {
|
|
style = Object.keys(layoutData.styles).map(key =>{
|
|
if (key === 'width' || key === 'height') return `${key}: 100%;`;
|
|
return `${key}: ${layoutData.styles[key]};`;
|
|
} ).join(' ');
|
|
}
|
|
|
|
return `<div class="dashboard-container" style="width: ${width}; height: ${height};">
|
|
<div class="handle">
|
|
${editButton}
|
|
</div>
|
|
<div class="dashboard-container-children" style="${style}">
|
|
${children}
|
|
</div>
|
|
</div>`;
|
|
}
|
|
|
|
addNewContainer(event) {
|
|
this.tempContainer = {
|
|
type: 'container',
|
|
styles: {
|
|
display: 'flex',
|
|
'flex-direction': 'row',
|
|
width: '100%',
|
|
height: '300px'
|
|
},
|
|
children: []
|
|
};
|
|
this.showContainerEditor(true);
|
|
}
|
|
|
|
editContainer(editContainerIndex) {
|
|
console.log('edit-container: ' + editContainerIndex);
|
|
this.tempContainer = JSON.parse(JSON.stringify(this.layoutData.children[editContainerIndex], LayoutUtil.echartReplacer));
|
|
this.showContainerEditor(false);
|
|
this.editContainerIndex = editContainerIndex;
|
|
}
|
|
|
|
removeContainer(containerIndex) {
|
|
console.log('edit-container: ' + containerIndex);
|
|
this.layoutData.children.splice(containerIndex, 1);
|
|
this.resetLayout();
|
|
}
|
|
|
|
addContainer(event) {
|
|
$('#container_editor_modal').find('input, select, textarea').each((index, element) => {
|
|
const fieldName = $(element).attr('name');
|
|
const newValue = LayoutUtil.getFieldValue(element);
|
|
if (fieldName !== '') {
|
|
_.set(this.tempContainer, fieldName, newValue);
|
|
}
|
|
});
|
|
this.layoutData.children.push(JSON.parse(JSON.stringify(this.tempContainer)));
|
|
this.tempContainer = null;
|
|
this.resetLayout();
|
|
$('#container_editor_modal').modal('hide');
|
|
}
|
|
|
|
saveContainer(event) {
|
|
console.log('save-container: ' + this.editContainerIndex);
|
|
$('#container_editor_modal').find('input, select, textarea').each((index, element) => {
|
|
const fieldName = $(element).attr('name');
|
|
const newValue = LayoutUtil.getFieldValue(element);
|
|
if (fieldName !== '') {
|
|
_.set(this.tempContainer, fieldName, newValue);
|
|
}
|
|
});
|
|
this.layoutData.children[this.editContainerIndex] = JSON.parse(JSON.stringify(this.tempContainer));
|
|
this.tempContainer = null;
|
|
this.resetLayout();
|
|
$('#container_editor_modal').modal('hide');
|
|
}
|
|
|
|
removeChart(containerIndex, columnIndex) {
|
|
this.layoutData.children[containerIndex].children.splice(columnIndex, 1);
|
|
this.resetLayout();
|
|
}
|
|
|
|
onRowsSorted(ui) {
|
|
let originalContainerIndex = ui.item.data('original_row_index');
|
|
this.updateLayoutDataRows(originalContainerIndex, ui);
|
|
}
|
|
|
|
onColumnsSorted(ui) {
|
|
let containerIndex = $('.dashboard-root').children('.dashboard-container').index(ui.item.closest('.dashboard-container'));
|
|
let originalContainerIndex = ui.item.data('original_row_index');
|
|
if (originalContainerIndex) {
|
|
if (originalContainerIndex === containerIndex) { // Check if the column moved from another row
|
|
this.updateLayoutDataWithinRow(ui.item);
|
|
} else { // The column was sorted within the same row
|
|
this.updateLayoutDataColumns(ui.item);
|
|
}
|
|
this.resetLayout();
|
|
}
|
|
|
|
}
|
|
|
|
updateLayoutDataRows(originalContainerIndex, ui) {
|
|
let targetIndex = $('.dashboard-root').children('.dashboard-container').index(ui.item.closest('.dashboard-container'));
|
|
|
|
if (targetIndex !== originalContainerIndex) {
|
|
this.layoutData.children.splice(targetIndex, 0, this.layoutData.children.splice(originalContainerIndex, 1)[0]);
|
|
}
|
|
console.log(this.layoutData);
|
|
}
|
|
|
|
updateLayoutDataWithinRow(movedItem) {
|
|
let oldContainerIndex = movedItem.data('original_row_index');
|
|
let oldIndex = movedItem.data('original_column_index');
|
|
|
|
if (oldContainerIndex !== -1 && oldIndex !== -1) {
|
|
let $row = movedItem.closest('.dashboard-container');
|
|
let newIndex = $row.children('.dashboard-chart').index(movedItem);
|
|
this.layoutData.children[oldContainerIndex].children.splice(newIndex, 0, this.layoutData.children[oldContainerIndex].children.splice(oldIndex, 1)[0]);
|
|
}
|
|
}
|
|
|
|
save() {
|
|
const jsonString = JSON.stringify(this.layoutData, LayoutUtil.echartReplacer);
|
|
return jsonString;
|
|
}
|
|
|
|
updateLayoutDataColumns(movedItem) {
|
|
// 새로운 행과 이전 행의 jQuery 요소를 가져옵니다
|
|
let $newRow = movedItem.closest('.dashboard-container');
|
|
|
|
// 이전 행의 레이아웃 데이터에서 이동된 행과 열의 인덱스를 찾습니다
|
|
let oldContainerIndex = movedItem.data('original_row_index');
|
|
let movedColumnIndex = movedItem.data('original_column_index');
|
|
|
|
if (oldContainerIndex !== -1 && movedColumnIndex !== undefined && movedColumnIndex !== -1) {
|
|
movedItem.data('original_row_index', -1);
|
|
movedItem.data('original_column_index', -1);
|
|
|
|
// 새 행의 인덱스를 찾습니다
|
|
let newContainerIndex = $('.dashboard-root').children('.dashboard-container').index($newRow);
|
|
|
|
// 이전 행에서 열 데이터를 추출합니다
|
|
let movedColumnData = this.layoutData.children[oldContainerIndex].children.splice(movedColumnIndex, 1)[0];
|
|
// 아이템이 드롭된 새 열 인덱스를 찾습니다
|
|
let newColumnIndex = movedItem.closest('.dashboard-container-children').children('.dashboard-chart').index(movedItem);
|
|
|
|
// 이동된 열 데이터를 새 행의 열에 새 인덱스에 삽입합니다
|
|
// 아이템이 마지막 위치로 이동된 경우 인덱스는 -1이 될 것이므로 이 경우를 처리합니다
|
|
if (newColumnIndex === -1) {
|
|
this.layoutData.children[newContainerIndex].children.push(movedColumnData);
|
|
} else {
|
|
this.layoutData.children[newContainerIndex].children.splice(newColumnIndex, 0, movedColumnData);
|
|
}
|
|
} else {
|
|
console.log('called twice on update');
|
|
}
|
|
}
|
|
|
|
showContainerEditor(isNew) {
|
|
if (isNew) {
|
|
$('.add-container').show();
|
|
$('.save-container').hide();
|
|
} else {
|
|
$('.add-container').hide();
|
|
$('.save-container').show();
|
|
}
|
|
let flatModel = LayoutUtil.flattenObject(JSON.parse(JSON.stringify(this.tempContainer)));
|
|
|
|
$('#container_editor_modal').find('input, select, textarea').each((index, element) => {
|
|
if ($(element).attr('type') === 'checkbox') {
|
|
$(element).prop('checked', false);
|
|
}
|
|
$(element).val('');
|
|
});
|
|
|
|
_.forEach(flatModel, (value, key) => {
|
|
if ($('#container_editor_modal').find(`input[name="${key}"]`).attr('type') === 'checkbox') {
|
|
$('#container_editor_modal').find(`input[name="${key}"]`).prop('checked', value);
|
|
} else {
|
|
$('#container_editor_modal').find(`input[name="${key}"], select[name="${key}"], textarea[name="${key}"]`).val(value);
|
|
}
|
|
});
|
|
|
|
$('#container_editor_modal').modal('show');
|
|
}
|
|
|
|
resize() {
|
|
console.log('resize');
|
|
this.dashboard.resizeAllCharts();
|
|
}
|
|
|
|
editDashboard(event) {
|
|
this.showDashboardEditor();
|
|
}
|
|
|
|
showDashboardEditor() {
|
|
let flatModel = LayoutUtil.flattenObject(JSON.parse(JSON.stringify(this.layoutData, LayoutUtil.echartReplacer)));
|
|
$('#dashboard_editor_modal').find('input, select, textarea').each((index, element) => {
|
|
if ($(element).attr('type') === 'checkbox') {
|
|
$(element).prop('checked', false);
|
|
}
|
|
$(element).val('');
|
|
});
|
|
|
|
_.forEach(flatModel, (value, key) => {
|
|
if ($('#dashboard_editor_modal').find(`input[name="${key}"]`).attr('type') === 'checkbox') {
|
|
$('#dashboard_editor_modal').find(`input[name="${key}"]`).prop('checked', value);
|
|
} else {
|
|
$('#dashboard_editor_modal').find(`input[name="${key}"], select[name="${key}"], textarea[name="${key}"]`).val(value);
|
|
}
|
|
});
|
|
|
|
$('#dashboard_editor_modal').modal('show');
|
|
}
|
|
|
|
saveDashboard(event) {
|
|
$('#dashboard_editor_modal').find('input, select, textarea').each((index, element) => {
|
|
const fieldName = $(element).attr('name');
|
|
const newValue = LayoutUtil.getFieldValue(element);
|
|
if (fieldName !== '') {
|
|
_.set(this.layoutData, fieldName, newValue);
|
|
}
|
|
});
|
|
console.log(this.layoutData);
|
|
this.resetLayout();
|
|
$('#dashboard_editor_modal').modal('hide');
|
|
}
|
|
|
|
bindEvents() {
|
|
$('.add-new-container').off('click').on('click', (event) => {
|
|
this.addNewContainer(event);
|
|
});
|
|
|
|
$('.edit-dashboard').off('click').on('click', (event) => {
|
|
this.editDashboard(event);
|
|
});
|
|
|
|
$('.save-dashboard').off('click').on('click', (event) => {
|
|
this.saveDashboard(event);
|
|
});
|
|
|
|
$('.remove-container').off('click').on('click', (event) => {
|
|
let containerIndex = $('.dashboard-root').children('.dashboard-container').index(event.target.closest('.dashboard-container'));
|
|
this.removeContainer(containerIndex);
|
|
});
|
|
|
|
$('.add-container').off('click').on('click', (event) => {
|
|
this.addContainer(event);
|
|
});
|
|
|
|
$('.save-container').off('click').on('click', (event) => {
|
|
this.saveContainer(event);
|
|
});
|
|
|
|
$('.edit-container').off('click').on('click', (event) => {
|
|
let editContainerIndex = $('.dashboard-root').children('.dashboard-container').index(event.target.closest('.dashboard-container'));
|
|
this.editContainer(editContainerIndex);
|
|
});
|
|
|
|
$('.edit-chart').off('click').on('click', (event) => {
|
|
let editContainerIndex = $('.dashboard-root').children('.dashboard-container').index(event.target.closest('.dashboard-container'));
|
|
let column = event.target.closest('.dashboard-chart');
|
|
let editColumnIndex = $(event.target.closest('.dashboard-container-children')).children('.dashboard-chart').index(column);
|
|
this.editChart(editContainerIndex, editColumnIndex);
|
|
});
|
|
|
|
$('.add-new-chart').off('click').on('click', (event) => {
|
|
let containerIndex = $('.dashboard-root').children('.dashboard-container').index(event.target.closest('.dashboard-container'));
|
|
this.addNewChart(containerIndex);
|
|
});
|
|
|
|
$('.remove-chart').off('click').on('click', (event) => {
|
|
let column = event.target.closest('.dashboard-chart');
|
|
let containerIndex = $('.dashboard-root').children('.dashboard-container').index(event.target.closest('.dashboard-container'));
|
|
let columnIndex = $(event.target.closest('.dashboard-container-children')).children('.dashboard-chart').index(column);
|
|
this.removeChart(containerIndex, columnIndex);
|
|
});
|
|
|
|
if ($('.dashboard-root').hasClass('ui-sortable')) {
|
|
$('.dashboard-root').sortable('destroy');
|
|
}
|
|
|
|
$('.dashboard-root').sortable({
|
|
handle: '.handle',
|
|
items: '.dashboard-container',
|
|
placeholder: 'ui-state-highlight',
|
|
start: (event, ui) => {
|
|
let originalRowIdx = $('.dashboard-root').children('.dashboard-container').index(ui.item.closest('.dashboard-container'));
|
|
ui.item.data('original_row_index', originalRowIdx);
|
|
}, update: (event, ui) => {
|
|
this.onRowsSorted(ui);
|
|
}
|
|
});
|
|
|
|
if ($('.dashboard-container').hasClass('ui-sortable')) {
|
|
$('.dashboard-container').sortable('destroy');
|
|
}
|
|
$('.dashboard-container-children').sortable({
|
|
// handle: ".handle",
|
|
placeholder: 'ui-state-highlight',
|
|
items: '.dashboard-chart',
|
|
connectWith: '.dashboard-container-children',
|
|
update: (event, ui) => {
|
|
this.onColumnsSorted(ui);
|
|
},
|
|
start: (event, ui) => {
|
|
let originalRowIdx = $('.dashboard-root').children('.dashboard-container').index(ui.item.closest('.dashboard-container'));
|
|
let originalColumnIdx = ui.item.closest('.dashboard-container-children').children('.dashboard-chart').index(ui.item);
|
|
ui.item.data('original_row_index', originalRowIdx);
|
|
ui.item.data('original_column_index', originalColumnIdx);
|
|
}
|
|
}).disableSelection();
|
|
}
|
|
|
|
}
|