Skip to content

Instantly share code, notes, and snippets.

@pavelpower
Last active April 1, 2022 11:07
Show Gist options
  • Save pavelpower/a7dfc40eff8c9375aaa30883b6671b8b to your computer and use it in GitHub Desktop.
Save pavelpower/a7dfc40eff8c9375aaa30883b6671b8b to your computer and use it in GitHub Desktop.
Run this script from console in your browser. Run this script on the page "https://miro.com/app/dashboard/"
function getBoardId(src) {
return src.match(/boards\/([^\/]*)/)[1];
}
function waitForElementToDisplay(selector, itemelem, callback, checkFrequencyInMs, timeoutInMs) {
var startTimeInMs = Date.now();
(function loopSearch() {
let btn = document.querySelectorAll(selector)[itemelem || 0];
if (btn != null) {
callback(btn);
return;
}
else {
setTimeout(function () {
if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs)
return;
loopSearch();
}, checkFrequencyInMs);
}
})();
}
function clickButton({ selector, itemelem, timewaitafter, callback }) {
waitForElementToDisplay(selector, itemelem, (btn)=> {
btn.click();
setTimeout(callback, timewaitafter || 500);
}, 1000, 9000);
}
function clickButtonMenu({ selector, itemelem, timewaitafter, callback, doCancel }) {
let btn = document.querySelectorAll(selector)[itemelem || 0];
if (btn==null) {
console.log('undefined by selector:', selector, itemelem || 0);
if (doCancel) doCancel();
}
if (btn.className.indexOf('exportItem_disabled') != -1) {
console.log('do cancel click on:', selector);
if (doCancel) doCancel();
}
btn.click();
setTimeout(callback, timewaitafter || 500);
}
function whileRtbLoader(callback) {
if (rtbLoader.rtbLoaderElement.style.display == 'block') {
setTimeout(()=>whileRtbLoader(callback), 500);
return;
}
if (document.querySelectorAll('.board-ui-skeleton__panel').length != 0) {
setTimeout(()=>whileRtbLoader(callback), 200);
return;
}
setTimeout(callback, 500);
}
function download(content, fileName, contentType, callback) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
if (!!callback) callback();
}
// open all boards
let btn = document.querySelectorAll('[aria-label="Show all boards"]')[0];
btn.click();
setTimeout(()=> {
var lsBoards = JSON.parse(window.localStorage.getItem('export_boards'));
if (lsBoards == null || lsBoards.length == 0) {
let boardsid = [];
let buttonImg = document.querySelectorAll('[data-testid="board_image_original_autotest_id"]');
buttonImg.forEach(b => boardsid.push(getBoardId(b.src)));
window.localStorage.setItem('export_boards', JSON.stringify(boardsid));
}
load();
function load() {
var boardsid = JSON.parse(window.localStorage.getItem('export_boards'));
// run
clickOpenAllBoards();
function clickOpenAllBoards() {
clickButton({
selector: '[aria-label="Show all boards"]',
itemelem: 0,
timewaitafter: 400,
callback: clickBoardIcon
})
}
function clickBoardIcon() {
let boardId = boardsid.pop();
window.localStorage.setItem('export_boards', JSON.stringify(boardsid));
//дашборды закончились
if (boardId == null)
return;
console.log(boardsid);
clickButton({
selector: `[src^="https://miro.com/api/v1/boards/${boardId}"]`,
itemelem: 0,
timewaitafter: 200,
callback: () => {
rtbLoader.rtbLoaderElement.style.display == 'block';
openExportMenu(clickExportBackup);
}
})
}
function openExportMenu(clickBtnExport) {
whileRtbLoader(()=> {
clickButton({
selector: '[data-testid="board-header__export-icon"]',
itemelem: 0,
timewaitafter: 500,
callback: clickBtnExport
});
});
}
function clickExportBackup() {
clickButtonMenu({
selector: '[data-testid="board-header__export-icon--BOARD_EXPORT_BACKUP"]',
itemelem: 0,
timewaitafter: 20000,
callback: backupBoardObjects,
doCancel: backupBoardObjects
});
}
function backupBoardObjects() {
window.miro.board.info.get().then(boardinfo=>{
const filename = boardinfo.title + '_' + boardinfo.updatedAt.replace(/\..*$/,'');
window.miro.board.getAllObjects().then(elems => {
const jsonData = JSON.stringify(elems, null, ' ');
download(jsonData, filename + '.canvas.json', 'text/plain', ()=>openExportMenu(clickExportPDF));
}).catch((err) => {
openExportMenu(clickExportPDF);
});
});
}
function clickExportPDF () {
window.miro.board.getAllObjects().then(elems => {
// chack have frame
if (elems.findIndex((k) => k.type == 'FRAME') == -1) {
backToPageAllDashboard();
return;
}
clickButtonMenu({
selector: '[data-testid="board-header__export-icon--BOARD_EXPORT_PDF"]',
itemelem: 0,
timewaitafter: 500,
callback: clickQualityBest,
doCancel: backToPageAllDashboard
});
});
function clickQualityBest () {
clickButton({
selector: '[hm-tap="modal.setQuality(+quality)"] label',
itemelem: 1,
timewaitafter: 300,
callback: clickDownloadPDF
});
}
function clickDownloadPDF () {
clickButton({
selector: 'button[hm-tap="modal.download()"]',
itemelem: 0,
timewaitafter: 20000, //wait 20 sec
callback: backToPageAllDashboard
});
}
}
function backToPageAllDashboard() {
window.history.back();
setTimeout(()=> {
load();
}, 10000);
}
}
}, 200);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment