123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- /**
- * Copyright (c) 2006-2017, JGraph Ltd
- * Copyright (c) 2006-2017, Gaudenz Alder
- */
- TrelloClient = function(editorUi)
- {
- DrawioClient.call(this, editorUi, 'tauth');
- Trello.setKey(this.key);
- };
- // Extends DrawioClient
- mxUtils.extend(TrelloClient, DrawioClient);
- TrelloClient.prototype.key = (window.location.hostname == 'test.draw.io') ?
- 'e73615c79cf7e381aef91c85936e9553' : 'e73615c79cf7e381aef91c85936e9553';
- TrelloClient.prototype.baseUrl = 'https://api.trello.com/1/';
- TrelloClient.prototype.SEPARATOR = '|$|';
- /**
- * Maximum attachment size of Trello.
- */
- TrelloClient.prototype.maxFileSize = 10000000 /*10MB*/;
- /**
- * Default extension for new files.
- */
- TrelloClient.prototype.extension = '.xml'; //TODO export to png
- /**
- *
- */
- TrelloClient.prototype.getLibrary = function(id, success, error)
- {
- this.getFile(id, success, error, false, true);
- };
- /**
- *
- */
- TrelloClient.prototype.getFile = function(id, success, error, denyConvert, asLibrary)
- {
- asLibrary = (asLibrary != null) ? asLibrary : false;
- Trello.authorize({
- type: 'popup',
- name: 'draw.io',
- scope: {
- read: 'true',
- write: 'true' },
- expiration: 'never',
- success: mxUtils.bind(this, function() {
- var ids = id.split(this.SEPARATOR);
- Trello.cards.get(ids[0] + '/attachments/' + ids[1], mxUtils.bind(this, function(meta)
- {
- //TODO Trello doesn't allow CORS requests to load attachments. Confirm that and make sure that only a proxy technique can work!
- // Handles .vsdx, Gliffy and PNG+XML files by creating a temporary file
- if ((/\.vsdx$/i.test(meta.name) || /\.gliffy$/i.test(meta.name) || /\.png$/i.test(meta.name)))
- {
- this.ui.convertFile(PROXY_URL + '?url=' + encodeURIComponent(meta.url), meta.name, meta.mimeType,
- this.extension, success, error);
- }
- else
- {
- var acceptResponse = true;
-
- var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
- {
- acceptResponse = false;
- error({code: App.ERROR_TIMEOUT})
- }), this.ui.timeout);
-
- this.ui.loadUrl(PROXY_URL + '?url=' + encodeURIComponent(meta.url), mxUtils.bind(this, function(data)
- {
- window.clearTimeout(timeoutThread);
-
- if (acceptResponse)
- {
- //keep our id which includes the cardId
- meta.compoundId = id;
-
- if (asLibrary)
- {
- success(new TrelloLibrary(this.ui, data, meta));
- }
- else
- {
- success(new TrelloFile(this.ui, data, meta));
- }
- }
- }), mxUtils.bind(this, function(req)
- {
- window.clearTimeout(timeoutThread);
-
- if (acceptResponse)
- {
- error();
- }
- }), meta.mimeType != null &&
- meta.mimeType.substring(0, 6) == 'image/');
- }
- }));
- }),
- error: error
- });
- };
- /**
- *
- */
- TrelloClient.prototype.insertLibrary = function(filename, data, success, error, cardId)
- {
- this.insertFile(filename, data, success, error, true, cardId);
- };
- /**
- *
- */
- TrelloClient.prototype.insertFile = function(filename, data, success, error, asLibrary, cardId)
- {
- asLibrary = (asLibrary != null) ? asLibrary : false;
-
- this.writeFile(filename, data, cardId, mxUtils.bind(this, function(meta)
- {
- if (asLibrary)
- {
- success(new TrelloLibrary(this.ui, data, meta));
- }
- else
- {
- success(new TrelloFile(this.ui, data, meta));
- }
- }), error);
- };
- /**
- *
- */
- TrelloClient.prototype.saveFile = function(file, success, error)
- {
- //delete file first, then write it again
- var ids = file.meta.compoundId.split(this.SEPARATOR);
- Trello.authorize({
- type: 'popup',
- name: 'draw.io',
- scope: {
- read: 'true',
- write: 'true'
- },
- expiration: 'never',
- success: mxUtils.bind(this, function()
- {
- Trello.del('cards/' + ids[0] + '/attachments/' + ids[1], mxUtils.bind(this, function()
- {
- this.writeFile(file.meta.name, file.getData(), ids[0], success, error);
- }), error);
- }),
- error: error
- });
- };
- /**
- *
- */
- TrelloClient.prototype.writeFile = function(filename, data, cardId, success, error)
- {
- if (filename != null && data != null)
- {
- if (data.length >= this.maxFileSize)
- {
- error({message: mxResources.get('drawingTooLarge') + ' (' +
- this.ui.formatFileSize(data.length) + ' / 10 MB)'});
-
- return;
- }
-
- Trello.authorize({
- type: 'popup',
- name: 'draw.io',
- scope: {
- read: 'true',
- write: 'true'
- },
- expiration: 'never',
- success: mxUtils.bind(this, function()
- {
- var acceptResponse = true;
-
- var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
- {
- acceptResponse = false;
- error({code: App.ERROR_TIMEOUT, retry: fn});
- }), this.ui.timeout);
-
- var formData = new FormData();
- formData.append("key", Trello.key());
- formData.append("token", Trello.token());
- formData.append("file", data);
- formData.append("name", filename);
- var request = new XMLHttpRequest();
- request.responseType = "json";
-
- request.onreadystatechange = mxUtils.bind(this, function()
- {
- if (request.readyState === 4)
- {
- window.clearTimeout(timeoutThread);
-
- if (acceptResponse)
- {
- if (request.status == 200)
- {
- var fileMeta = request.response;
- fileMeta.compoundId = cardId + this.SEPARATOR + fileMeta.id
- success(fileMeta);
- }
- else
- {
- error();
- }
- }
- }
- });
-
- request.open("POST", this.baseUrl + 'cards/' + cardId + '/attachments');
- request.send(formData);
- }),
- error: error
- });
- }
- else
- {
- error({message: mxResources.get('unknownError')});
- }
- };
- /**
- * Checks if the client is authorized and calls the next step.
- */
- TrelloClient.prototype.pickLibrary = function(fn)
- {
- this.pickFile(fn);
- };
- /**
- *
- */
- TrelloClient.prototype.pickFolder = function(fn)
- {
- Trello.authorize({
- type: 'popup',
- name: 'draw.io',
- scope: {
- read: 'true',
- write: 'true' },
- expiration: 'never',
- success: mxUtils.bind(this, function() {
- //show file select
- this.showTrelloDialog(false, fn);
- }),
- error: mxUtils.bind(this, function(e)
- {
- this.ui.showError(mxResources.get('error'), e);
- })
- });
- };
- /**
- * Checks if the client is authorized and calls the next step.
- */
- TrelloClient.prototype.pickFile = function(fn, returnObject)
- {
- fn = (fn != null) ? fn : mxUtils.bind(this, function(id)
- {
- this.ui.loadFile('T' + encodeURIComponent(id));
- });
-
- Trello.authorize({
- type: 'popup',
- name: 'draw.io',
- scope: {
- read: 'true',
- write: 'true' },
- expiration: 'never',
- success: mxUtils.bind(this, function() {
- //show file select
- this.showTrelloDialog(true, fn);
- }),
- error: mxUtils.bind(this, function(e)
- {
- this.ui.showError(mxResources.get('error'), e);
- })
- });
- };
- /**
- *
- */
- TrelloClient.prototype.showTrelloDialog = function(showFiles, fn)
- {
- var cardId = null;
- var filter = null;
- var linkCounter = 0;
-
- var content = document.createElement('div');
- content.style.whiteSpace = 'nowrap';
- content.style.overflow = 'hidden';
- content.style.height = '224px';
- var hd = document.createElement('h3');
- mxUtils.write(hd, showFiles? mxResources.get('selectFile') : mxResources.get('selectCard'));
- hd.style.cssText = 'width:100%;text-align:center;margin-top:0px;margin-bottom:12px';
- content.appendChild(hd);
- var div = document.createElement('div');
- div.style.whiteSpace = 'nowrap';
- div.style.overflow = 'auto';
- div.style.height = '194px';
- content.appendChild(div);
- var dlg = new CustomDialog(this.ui, content);
- this.ui.showDialog(dlg.container, 340, 270, true, true);
-
- dlg.okButton.parentNode.removeChild(dlg.okButton);
-
- var createLink = mxUtils.bind(this, function(label, fn, preview)
- {
- linkCounter++;
- var div = document.createElement('div');
- div.style = "width:100%;vertical-align:middle;background:" + (linkCounter % 2 == 0? "#eee" : "#fff");
- var link = document.createElement('a');
- link.setAttribute('href', 'javascript:void(0);');
-
- if (preview != null)
- {
- var img = document.createElement('img');
- img.src = preview.url;
- img.width = preview.width;
- img.height= preview.height;
- img.style= "border: 1px solid black;margin:5px;vertical-align:middle"
- link.appendChild(img);
- }
-
- mxUtils.write(link, label);
- mxEvent.addListener(link, 'click', fn);
-
- div.appendChild(link);
-
- return div;
- });
-
- var error = mxUtils.bind(this, function(err)
- {
- this.ui.handleError(err, null, mxUtils.bind(this, function()
- {
- this.ui.spinner.stop();
-
- this.ui.hideDialog();
- }));
- });
-
- var selectAtt = mxUtils.bind(this, function()
- {
- linkCounter = 0;
- div.innerHTML = '';
- this.ui.spinner.spin(div, mxResources.get('loading'));
-
- Trello.cards.get(cardId + '/attachments', {fields: 'id,name,previews'}, mxUtils.bind(this, function(data)
- {
- this.ui.spinner.stop();
- var files = data;
- div.appendChild(createLink('../ [Up]', mxUtils.bind(this, function()
- {
- selectCard();
- })));
- mxUtils.br(div);
- if (files == null || files.length == 0)
- {
- mxUtils.write(div, mxResources.get('noFiles'));
- }
- else
- {
- var listFiles = mxUtils.bind(this, function()
- {
- for (var i = 0; i < files.length; i++)
- {
- (mxUtils.bind(this, function(file)
- {
- div.appendChild(createLink(file.name, mxUtils.bind(this, function()
- {
- this.ui.hideDialog();
- fn(cardId + this.SEPARATOR + file.id);
- }), file.previews != null? file.previews[0] : null));
- }))(files[i]);
- }
- });
-
- listFiles();
- }
- }), error);
- });
-
- // Adds paging for cards (files limited to 1000 by API)
- var pageSize = 100;
- var nextPageDiv = null;
- var scrollFn = null;
- var selectCard = mxUtils.bind(this, function(page)
- {
- if (page == null)
- {
- linkCounter = 0;
- div.innerHTML = '';
- page = 1;
- }
-
- this.ui.spinner.spin(div, mxResources.get('loading'));
-
- if (nextPageDiv != null && nextPageDiv.parentNode != null)
- {
- nextPageDiv.parentNode.removeChild(nextPageDiv);
- }
-
- nextPageDiv = document.createElement('a');
- nextPageDiv.style.display = 'block';
- nextPageDiv.setAttribute('href', 'javascript:void(0);');
- mxUtils.write(nextPageDiv, mxResources.get('more') + '...');
-
- var nextPage = mxUtils.bind(this, function()
- {
- mxEvent.removeListener(div, 'scroll', scrollFn);
- selectCard(page + 1);
- });
-
- mxEvent.addListener(nextPageDiv, 'click', nextPage);
-
- Trello.get('search', {
- 'query': (filter != null ? filter : 'is:open'),
- 'cards_limit': pageSize,
- 'cards_page': page-1
- },
- mxUtils.bind(this, function(data)
- {
- this.ui.spinner.stop();
- var cards = (data != null) ? data.cards : null;
-
- if (cards == null || cards.length == 0)
- {
- if (filter != null)
- {
- div.appendChild(createLink(mxResources.get('clearFilter'), mxUtils.bind(this, function()
- {
- filter = null;
- selectCard();
- })));
- mxUtils.br(div);
- }
- mxUtils.write(div, mxResources.get('noFiles'));
- }
- else
- {
- if (page == 1)
- {
- if (filter != null)
- {
- div.appendChild(createLink(mxResources.get('clearFilter'), mxUtils.bind(this, function()
- {
- filter = null;
- selectCard();
- })));
- }
- else
- {
- div.appendChild(createLink(mxResources.get('filterCards') + '...', mxUtils.bind(this, function()
- {
- var dlg = new FilenameDialog(this.ui, 'is:open', mxResources.get('ok'), mxUtils.bind(this, function(value)
- {
- if (value != null)
- {
- filter = value;
- selectCard();
- }
- }), mxResources.get('cardName'), null, null, 'http://help.trello.com/article/808-searching-for-cards-all-boards');
- this.ui.showDialog(dlg.container, 300, 80, true, false);
- dlg.init();
- })));
- }
-
- mxUtils.br(div);
- }
-
- for (var i = 0; i < cards.length; i++)
- {
- (mxUtils.bind(this, function(card)
- {
- div.appendChild(createLink(card.name, mxUtils.bind(this, function()
- {
- if (showFiles)
- {
- cardId = card.id;
- selectAtt();
- }
- else
- {
- this.ui.hideDialog();
- fn(card.id);
- }
- })));
- }))(cards[i]);
- }
- }
-
- if (cards.length == pageSize)
- {
- div.appendChild(nextPageDiv);
-
- scrollFn = function()
- {
- if (div.scrollTop >= div.scrollHeight - div.offsetHeight)
- {
- nextPage();
- }
- };
-
- mxEvent.addListener(div, 'scroll', scrollFn);
- }
- }),
- error);
- });
-
- selectCard();
- };
- /**
- * Checks if the client is authorized
- */
- TrelloClient.prototype.isAuthorized = function()
- {
- //TODO this may break if Trello client.js is changed
- return localStorage["trello_token"] != null; //Trello.authorized(); doesn't work unless authorize is called first
- };
- /**
- * Logout and deauthorize the user.
- */
- TrelloClient.prototype.logout = function()
- {
- Trello.deauthorize();
- };
|