|
@@ -0,0 +1,804 @@
|
|
|
+/**
|
|
|
+ * Copyright (c) 2006-2021, JGraph Ltd
|
|
|
+ * Copyright (c) 2006-2021, draw.io AG
|
|
|
+ */
|
|
|
+
|
|
|
+//Add a closure to hide the class private variables without changing the code a lot
|
|
|
+(function ()
|
|
|
+{
|
|
|
+
|
|
|
+var _token = null;
|
|
|
+
|
|
|
+window.NotionClient = function(editorUi)
|
|
|
+{
|
|
|
+ DrawioClient.call(this, editorUi, 'notionAuthInfo');
|
|
|
+};
|
|
|
+
|
|
|
+// Extends DrawioClient
|
|
|
+mxUtils.extend(NotionClient, DrawioClient);
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.extension = '.drawio';
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.baseUrl = window.NOTION_API_URL || ((window.location.hostname == 'test.draw.io') ?
|
|
|
+ 'https://notion.jgraph.workers.dev/api' : '/notion-api');
|
|
|
+
|
|
|
+NotionClient.prototype.getTitle = function (obj)
|
|
|
+{
|
|
|
+ if (typeof obj.title === 'string')
|
|
|
+ {
|
|
|
+ return obj.title;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var title = [];
|
|
|
+
|
|
|
+ for (var i = 0; i < obj.title.length; i++)
|
|
|
+ {
|
|
|
+ title.push(obj.title[i].text.content)
|
|
|
+ }
|
|
|
+
|
|
|
+ return title.join(' ');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+NotionClient.prototype.authenticate = function(success, error, failOnAuth)
|
|
|
+{
|
|
|
+ var acceptAuthResponse = true;
|
|
|
+
|
|
|
+ var errFn = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ if (acceptAuthResponse)
|
|
|
+ {
|
|
|
+ acceptAuthResponse = false;
|
|
|
+ error({message: mxResources.get('accessDenied'), retry: mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ this.ui.hideDialog();
|
|
|
+ auth();
|
|
|
+ })});
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ var auth = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ acceptAuthResponse = true;
|
|
|
+
|
|
|
+ this.ui.showAuthDialog(this, true, mxUtils.bind(this, function(remember, authSuccess)
|
|
|
+ {
|
|
|
+ var tokenDlg = new FilenameDialog(this.ui, '',
|
|
|
+ mxResources.get('ok'), mxUtils.bind(this, function(token)
|
|
|
+ {
|
|
|
+ //check token is valid
|
|
|
+ _token = token;
|
|
|
+
|
|
|
+ //TODO use any simpler request if one becomes available
|
|
|
+ this.executeRequest('/v1/databases', null, 'GET', mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ this.executeRequest('/setToken', null, 'GET', mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ acceptAuthResponse = false;
|
|
|
+
|
|
|
+ if (remember)
|
|
|
+ {
|
|
|
+ _token = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (authSuccess != null)
|
|
|
+ {
|
|
|
+ authSuccess();
|
|
|
+ }
|
|
|
+
|
|
|
+ success();
|
|
|
+ }), errFn, failOnAuth);
|
|
|
+ }), errFn, failOnAuth);
|
|
|
+ }), mxResources.get('notionToken'), function(token)
|
|
|
+ {
|
|
|
+ return token != null && token.length > 0;
|
|
|
+ }, null, 'https://developers.notion.com/docs/getting-started#step-1-create-an-integration');
|
|
|
+
|
|
|
+ this.ui.showDialog(tokenDlg.container, 300, 80, true, true);
|
|
|
+ tokenDlg.init();
|
|
|
+ }), errFn);
|
|
|
+ });
|
|
|
+
|
|
|
+ auth();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Checks if the client is authorized and calls the next step.
|
|
|
+ */
|
|
|
+NotionClient.prototype.executeRequest = function(url, data, method, success, error, failOnAuth)
|
|
|
+{
|
|
|
+ var doExecute = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ var acceptResponse = true;
|
|
|
+
|
|
|
+ var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ acceptResponse = false;
|
|
|
+ error({code: App.ERROR_TIMEOUT, retry: doExecute});
|
|
|
+ }), this.ui.timeout);
|
|
|
+
|
|
|
+ var req = new mxXmlRequest(this.baseUrl + url, data, method);
|
|
|
+
|
|
|
+ req.withCredentials = true;
|
|
|
+
|
|
|
+ req.setRequestHeaders = mxUtils.bind(this, function(request, params)
|
|
|
+ {
|
|
|
+ if (_token != null)
|
|
|
+ {
|
|
|
+ request.setRequestHeader('Authorization', 'Bearer ' + _token);
|
|
|
+ }
|
|
|
+
|
|
|
+ request.setRequestHeader('Notion-Version', '2021-05-13');
|
|
|
+ request.setRequestHeader('Content-Type', 'application/json');
|
|
|
+ });
|
|
|
+
|
|
|
+ req.send(mxUtils.bind(this, function(req)
|
|
|
+ {
|
|
|
+ window.clearTimeout(timeoutThread);
|
|
|
+
|
|
|
+ if (acceptResponse)
|
|
|
+ {
|
|
|
+ // 404 (file not found) is a valid response for checkExists
|
|
|
+ if (req.getStatus() >= 200 && req.getStatus() <= 299)
|
|
|
+ {
|
|
|
+ if (this.user == null)
|
|
|
+ {
|
|
|
+ this.setUser(new DrawioUser('notion', null, 'Notion'));
|
|
|
+ }
|
|
|
+
|
|
|
+ success(JSON.parse(req.getText()));
|
|
|
+ }
|
|
|
+ else if (!failOnAuth && (req.getStatus() === 401 || req.getStatus() === 400))
|
|
|
+ {
|
|
|
+ this.setUser(null);
|
|
|
+ failOnAuth = true;
|
|
|
+ //Authorize again using the refresh token
|
|
|
+ this.authenticate(function()
|
|
|
+ {
|
|
|
+ doExecute();
|
|
|
+ }, error, failOnAuth);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error(this.parseRequestText(req));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }), mxUtils.bind(this, function(err)
|
|
|
+ {
|
|
|
+ window.clearTimeout(timeoutThread);
|
|
|
+
|
|
|
+ if (acceptResponse)
|
|
|
+ {
|
|
|
+ error(err);
|
|
|
+ }
|
|
|
+ }));
|
|
|
+ });
|
|
|
+
|
|
|
+ doExecute();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.getLibrary = function(id, success, error)
|
|
|
+{
|
|
|
+ this.getFile(id, success, error, false, true);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.getFile = function(id, success, error, denyConvert, asLibrary)
|
|
|
+{
|
|
|
+ asLibrary = (asLibrary != null) ? asLibrary : false;
|
|
|
+
|
|
|
+ this.executeRequest('/v1/pages/' + encodeURIComponent(id), null, 'GET', mxUtils.bind(this, function(fileInfo)
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var xmlParts = fileInfo.properties.xml.rich_text, xml = '';
|
|
|
+ var fileName = this.getTitle(fileInfo.properties.Name);
|
|
|
+
|
|
|
+ for (var i = 0; i < xmlParts.length; i++)
|
|
|
+ {
|
|
|
+ xml += xmlParts[i].text.content;
|
|
|
+ }
|
|
|
+
|
|
|
+ var meta = {id: id, name: fileName};
|
|
|
+
|
|
|
+ if (asLibrary)
|
|
|
+ {
|
|
|
+ success(new NotionLibrary(this.ui, xml, meta));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ success(new NotionFile(this.ui, xml, meta));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(e)
|
|
|
+ {
|
|
|
+ if (error != null)
|
|
|
+ {
|
|
|
+ error(e);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }), error);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.insertLibrary = function(filename, data, success, error, folderId)
|
|
|
+{
|
|
|
+ this.insertFile(filename, data, success, error, true, folderId);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.insertFile = function(filename, data, success, error, asLibrary, folderId)
|
|
|
+{
|
|
|
+ asLibrary = (asLibrary != null) ? asLibrary : false;
|
|
|
+
|
|
|
+ this.checkExists(folderId, filename, true, mxUtils.bind(this, function(checked, currentId)
|
|
|
+ {
|
|
|
+ if (checked)
|
|
|
+ {
|
|
|
+ this.writeFile(currentId? '/v1/pages/' + encodeURIComponent(currentId) : '/v1/pages',
|
|
|
+ currentId? null : folderId, filename, data, currentId? 'PATCH' : 'POST',
|
|
|
+ mxUtils.bind(this, function(fileInfo)
|
|
|
+ {
|
|
|
+ var meta = {id: fileInfo.id, name: this.getTitle(fileInfo.properties.Name)};
|
|
|
+
|
|
|
+ if (asLibrary)
|
|
|
+ {
|
|
|
+ success(new NotionLibrary(this.ui, data, meta));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ success(new NotionFile(this.ui, data, meta));
|
|
|
+ }
|
|
|
+ }), error);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error();
|
|
|
+ }
|
|
|
+ }))
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.checkExists = function(parentId, filename, askReplace, fn)
|
|
|
+{
|
|
|
+ this.executeRequest('/v1/databases/' + encodeURIComponent(parentId) + '/query', JSON.stringify({
|
|
|
+ filter: {
|
|
|
+ property: 'Name',
|
|
|
+ text: {
|
|
|
+ equals: filename
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }), 'POST', mxUtils.bind(this, function(resp)
|
|
|
+ {
|
|
|
+ if (resp.results.length == 0)
|
|
|
+ {
|
|
|
+ fn(true);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (askReplace)
|
|
|
+ {
|
|
|
+ this.ui.spinner.stop();
|
|
|
+
|
|
|
+ this.ui.confirm(mxResources.get('replaceIt', [filename]), function()
|
|
|
+ {
|
|
|
+ fn(true, resp.results[0].id);
|
|
|
+ }, function()
|
|
|
+ {
|
|
|
+ fn(false);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this.ui.spinner.stop();
|
|
|
+
|
|
|
+ this.ui.showError(mxResources.get('error'), mxResources.get('fileExists'), mxResources.get('ok'), function()
|
|
|
+ {
|
|
|
+ fn(false);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }), function(req)
|
|
|
+ {
|
|
|
+ fn(false);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.saveFile = function(file, success, error)
|
|
|
+{
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var data = file.getData();
|
|
|
+
|
|
|
+ this.writeFile('/v1/pages/' + file.getId(), null, file.getTitle(), data,
|
|
|
+ 'PATCH', mxUtils.bind(this, function(resp)
|
|
|
+ {
|
|
|
+ success(resp, data);
|
|
|
+ }), error);
|
|
|
+ }
|
|
|
+ catch (e)
|
|
|
+ {
|
|
|
+ error(e);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.writeFile = function(url, folderId, filename, data, method, success, error)
|
|
|
+{
|
|
|
+ try
|
|
|
+ {
|
|
|
+ if (url != null && data != null)
|
|
|
+ {
|
|
|
+ //Notion has a limit on rich-text pages of 200KB
|
|
|
+ if (data.length > 200000 /*200KB*/)
|
|
|
+ {
|
|
|
+ error({message: mxResources.get('drawingTooLarge') + ' (' +
|
|
|
+ this.ui.formatFileSize(data.length) + ' / 200 KB)'});
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var richTxt = []
|
|
|
+ var parts = Math.ceil(data.length / 2000);
|
|
|
+
|
|
|
+ for (var i = 0; i < parts; i++)
|
|
|
+ {
|
|
|
+ richTxt.push({
|
|
|
+ text: {
|
|
|
+ content: data.substr(i * 2000, 2000)
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ var reqBody = {
|
|
|
+ properties: {
|
|
|
+ Name: {
|
|
|
+ title: [{
|
|
|
+ text: {
|
|
|
+ content: filename
|
|
|
+ }
|
|
|
+ }]
|
|
|
+ },
|
|
|
+ xml: {
|
|
|
+ rich_text: richTxt
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ if (folderId)
|
|
|
+ {
|
|
|
+ reqBody['parent'] = { database_id: folderId };
|
|
|
+ }
|
|
|
+
|
|
|
+ this.executeRequest(url, JSON.stringify(reqBody), method, success, error);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ error({message: mxResources.get('unknownError')});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (e)
|
|
|
+ {
|
|
|
+ error(e);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.parseRequestText = function(req)
|
|
|
+{
|
|
|
+ var result = {message: mxResources.get('unknownError')};
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ result = JSON.parse(req.getText());
|
|
|
+ }
|
|
|
+ catch (e)
|
|
|
+ {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Checks if the client is authorized and calls the next step.
|
|
|
+ */
|
|
|
+NotionClient.prototype.pickLibrary = function(fn)
|
|
|
+{
|
|
|
+ this.pickFile(fn);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ * Checks if the client is authorized and calls the next step.
|
|
|
+ */
|
|
|
+NotionClient.prototype.pickFolder = function(fn)
|
|
|
+{
|
|
|
+ this.showNotionDialog(false, fn);
|
|
|
+};
|
|
|
+
|
|
|
+NotionClient.prototype.pickFile = function(fn)
|
|
|
+{
|
|
|
+ fn = (fn != null) ? fn : mxUtils.bind(this, function(id)
|
|
|
+ {
|
|
|
+ this.ui.loadFile('N' + encodeURIComponent(id));
|
|
|
+ });
|
|
|
+
|
|
|
+ this.showNotionDialog(true, fn);
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.showNotionDialog = function(showFiles, fn)
|
|
|
+{
|
|
|
+ var itemId, itemName;
|
|
|
+
|
|
|
+ var content = document.createElement('div');
|
|
|
+ content.style.whiteSpace = 'nowrap';
|
|
|
+ content.style.overflow = 'hidden';
|
|
|
+ content.style.height = '304px';
|
|
|
+
|
|
|
+ var hd = document.createElement('h3');
|
|
|
+ mxUtils.write(hd, mxResources.get((showFiles) ? 'officeSelDiag' : 'selectDB'));
|
|
|
+ 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.border = '1px solid lightgray';
|
|
|
+ div.style.boxSizing = 'border-box';
|
|
|
+ div.style.padding = '4px';
|
|
|
+ div.style.overflow = 'auto';
|
|
|
+ div.style.lineHeight = '1.2em';
|
|
|
+ div.style.height = '274px';
|
|
|
+ content.appendChild(div);
|
|
|
+
|
|
|
+ var listItem = document.createElement('div');
|
|
|
+ listItem.style.textOverflow = 'ellipsis';
|
|
|
+ listItem.style.boxSizing = 'border-box';
|
|
|
+ listItem.style.overflow = 'hidden';
|
|
|
+ listItem.style.padding = '4px';
|
|
|
+ listItem.style.width = '100%';
|
|
|
+
|
|
|
+ var dlg = new CustomDialog(this.ui, content, mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ fn(itemId);
|
|
|
+ }));
|
|
|
+ this.ui.showDialog(dlg.container, 420, 360, true, true);
|
|
|
+
|
|
|
+ if (showFiles)
|
|
|
+ {
|
|
|
+ dlg.okButton.parentNode.removeChild(dlg.okButton);
|
|
|
+ }
|
|
|
+
|
|
|
+ var createLink = mxUtils.bind(this, function(label, exec, padding, underline)
|
|
|
+ {
|
|
|
+ var link = document.createElement('a');
|
|
|
+ link.setAttribute('title', label);
|
|
|
+ link.style.cursor = 'pointer';
|
|
|
+ mxUtils.write(link, label);
|
|
|
+ mxEvent.addListener(link, 'click', exec);
|
|
|
+
|
|
|
+ if (underline)
|
|
|
+ {
|
|
|
+ link.style.textDecoration = 'underline';
|
|
|
+ }
|
|
|
+
|
|
|
+ if (padding != null)
|
|
|
+ {
|
|
|
+ var temp = listItem.cloneNode();
|
|
|
+ temp.style.padding = padding;
|
|
|
+ temp.appendChild(link);
|
|
|
+
|
|
|
+ link = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ return link;
|
|
|
+ });
|
|
|
+
|
|
|
+ var updatePathInfo = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ var dbInfo = document.createElement('div');
|
|
|
+ dbInfo.style.marginBottom = '8px';
|
|
|
+
|
|
|
+ dbInfo.appendChild(createLink(itemName, mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ itemId = null;
|
|
|
+ selectDB();
|
|
|
+ }), null, true));
|
|
|
+
|
|
|
+ div.appendChild(dbInfo);
|
|
|
+ });
|
|
|
+
|
|
|
+ var error = mxUtils.bind(this, function(err)
|
|
|
+ {
|
|
|
+ // Pass a dummy notFoundMessage to bypass special handling
|
|
|
+ this.ui.handleError(err, null, mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ this.ui.spinner.stop();
|
|
|
+
|
|
|
+ if (this.getUser() != null)
|
|
|
+ {
|
|
|
+ itemId = null;
|
|
|
+
|
|
|
+ selectDB();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this.ui.hideDialog();
|
|
|
+ }
|
|
|
+ }), null, {});
|
|
|
+ });
|
|
|
+
|
|
|
+ // Adds paging for DBs and diagrams (DB pages)
|
|
|
+ var nextPageDiv = null;
|
|
|
+ var scrollFn = null;
|
|
|
+ var pageSize = 100;
|
|
|
+
|
|
|
+ var selectFile = mxUtils.bind(this, function(nextCursor)
|
|
|
+ {
|
|
|
+ if (nextCursor == null)
|
|
|
+ {
|
|
|
+ div.innerHTML = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ this.ui.spinner.spin(div, mxResources.get('loading'));
|
|
|
+ dlg.okButton.removeAttribute('disabled');
|
|
|
+
|
|
|
+ if (scrollFn != null)
|
|
|
+ {
|
|
|
+ mxEvent.removeListener(div, 'scroll', scrollFn);
|
|
|
+ scrollFn = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nextPageDiv != null && nextPageDiv.parentNode != null)
|
|
|
+ {
|
|
|
+ nextPageDiv.parentNode.removeChild(nextPageDiv);
|
|
|
+ }
|
|
|
+
|
|
|
+ nextPageDiv = document.createElement('a');
|
|
|
+ nextPageDiv.style.display = 'block';
|
|
|
+ nextPageDiv.style.cursor = 'pointer';
|
|
|
+ mxUtils.write(nextPageDiv, mxResources.get('more') + '...');
|
|
|
+
|
|
|
+ var nextPage = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ selectFile(nextCursor);
|
|
|
+ });
|
|
|
+
|
|
|
+ mxEvent.addListener(nextPageDiv, 'click', nextPage);
|
|
|
+
|
|
|
+ var reqBody = {
|
|
|
+ page_size: pageSize
|
|
|
+ };
|
|
|
+
|
|
|
+ if (nextCursor != null)
|
|
|
+ {
|
|
|
+ reqBody.start_cursor = nextCursor;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.executeRequest('/v1/databases/' + encodeURIComponent(itemId) + '/query',
|
|
|
+ JSON.stringify(reqBody), 'POST', mxUtils.bind(this, function(resp)
|
|
|
+ {
|
|
|
+ this.ui.spinner.stop();
|
|
|
+
|
|
|
+ if (nextCursor == null)
|
|
|
+ {
|
|
|
+ updatePathInfo();
|
|
|
+
|
|
|
+ div.appendChild(createLink('../ [Up]', mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ itemId = null;
|
|
|
+ selectDB();
|
|
|
+ }), '4px'));
|
|
|
+ }
|
|
|
+
|
|
|
+ var files = resp.results;
|
|
|
+
|
|
|
+ if (files == null || files.length == 0)
|
|
|
+ {
|
|
|
+ mxUtils.write(div, mxResources.get('noFiles'));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ var gray = true;
|
|
|
+
|
|
|
+ for (var i = 0; i < files.length; i++)
|
|
|
+ {
|
|
|
+ (mxUtils.bind(this, function(file, idx)
|
|
|
+ {
|
|
|
+ var temp = listItem.cloneNode();
|
|
|
+ temp.style.backgroundColor = (gray) ?
|
|
|
+ ((Editor.isDarkMode()) ? '#000000' : '#eeeeee') : '';
|
|
|
+ gray = !gray;
|
|
|
+
|
|
|
+ var typeImg = document.createElement('img');
|
|
|
+ typeImg.src = IMAGE_PATH + '/file.png';
|
|
|
+ typeImg.setAttribute('align', 'absmiddle');
|
|
|
+ typeImg.style.marginRight = '4px';
|
|
|
+ typeImg.style.marginTop = '-4px';
|
|
|
+ typeImg.width = 20;
|
|
|
+ temp.appendChild(typeImg);
|
|
|
+
|
|
|
+ temp.appendChild(createLink(this.getTitle(file.properties.Name), mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ this.ui.hideDialog();
|
|
|
+ fn(file.id);
|
|
|
+ })));
|
|
|
+
|
|
|
+ div.appendChild(temp);
|
|
|
+ }))(files[i], i);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (resp.has_more)
|
|
|
+ {
|
|
|
+ nextCursor = resp.next_cursor;
|
|
|
+
|
|
|
+ div.appendChild(nextPageDiv);
|
|
|
+
|
|
|
+ scrollFn = function()
|
|
|
+ {
|
|
|
+ if (div.scrollTop >= div.scrollHeight - div.offsetHeight)
|
|
|
+ {
|
|
|
+ nextPage();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ mxEvent.addListener(div, 'scroll', scrollFn);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }), error, true);
|
|
|
+ });
|
|
|
+
|
|
|
+ var selectDB = mxUtils.bind(this, function(nextCursor)
|
|
|
+ {
|
|
|
+ if (nextCursor == null)
|
|
|
+ {
|
|
|
+ div.innerHTML = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ dlg.okButton.setAttribute('disabled', 'disabled');
|
|
|
+ this.ui.spinner.spin(div, mxResources.get('loading'));
|
|
|
+
|
|
|
+ if (scrollFn != null)
|
|
|
+ {
|
|
|
+ mxEvent.removeListener(div, 'scroll', scrollFn);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (nextPageDiv != null && nextPageDiv.parentNode != null)
|
|
|
+ {
|
|
|
+ nextPageDiv.parentNode.removeChild(nextPageDiv);
|
|
|
+ }
|
|
|
+
|
|
|
+ nextPageDiv = document.createElement('a');
|
|
|
+ nextPageDiv.style.display = 'block';
|
|
|
+ nextPageDiv.style.cursor = 'pointer';
|
|
|
+ mxUtils.write(nextPageDiv, mxResources.get('more') + '...');
|
|
|
+
|
|
|
+ var nextPage = mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ selectDB(nextCursor);
|
|
|
+ });
|
|
|
+
|
|
|
+ mxEvent.addListener(nextPageDiv, 'click', nextPage);
|
|
|
+
|
|
|
+ this.executeRequest('/v1/databases?page_size=' + pageSize + (nextCursor != null? '&start_cursor=' + nextCursor : ''),
|
|
|
+ null, 'GET', mxUtils.bind(this, function(resp)
|
|
|
+ {
|
|
|
+ this.ui.spinner.stop();
|
|
|
+ var dbs = resp.results;
|
|
|
+ var count = 0;
|
|
|
+
|
|
|
+ if (dbs == null || dbs.length == 0)
|
|
|
+ {
|
|
|
+ mxUtils.write(div, mxResources.get('noDBs'));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (var i = 0; i < dbs.length; i++)
|
|
|
+ {
|
|
|
+ if (!dbs[i].properties.Name || dbs[i].properties.Name.type != 'title'
|
|
|
+ || !dbs[i].properties.xml || dbs[i].properties.xml.type != 'rich_text') continue;
|
|
|
+
|
|
|
+ (mxUtils.bind(this, function(db, idx)
|
|
|
+ {
|
|
|
+ var temp = listItem.cloneNode();
|
|
|
+ temp.style.backgroundColor = (idx % 2 == 0) ?
|
|
|
+ ((Editor.isDarkMode()) ? '#000000' : '#eeeeee') : '';
|
|
|
+
|
|
|
+ temp.appendChild(createLink(this.getTitle(db), mxUtils.bind(this, function()
|
|
|
+ {
|
|
|
+ itemId = db.id;
|
|
|
+ itemName = this.getTitle(db);
|
|
|
+
|
|
|
+ if (showFiles)
|
|
|
+ {
|
|
|
+ selectFile();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ this.ui.hideDialog();
|
|
|
+ fn(itemId);
|
|
|
+ }
|
|
|
+ })));
|
|
|
+
|
|
|
+ div.appendChild(temp);
|
|
|
+ }))(dbs[i], i);
|
|
|
+
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (resp.has_more)
|
|
|
+ {
|
|
|
+ nextCursor = resp.next_cursor;
|
|
|
+
|
|
|
+ if (count == 0)
|
|
|
+ {
|
|
|
+ nextPage();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ div.appendChild(nextPageDiv);
|
|
|
+
|
|
|
+ scrollFn = function()
|
|
|
+ {
|
|
|
+ if (div.scrollTop >= div.scrollHeight - div.offsetHeight)
|
|
|
+ {
|
|
|
+ nextPage();
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ mxEvent.addListener(div, 'scroll', scrollFn);
|
|
|
+ }
|
|
|
+ else if (count == 0 && div.innerHTML == '')
|
|
|
+ {
|
|
|
+ mxUtils.write(div, mxResources.get('noDBs'));
|
|
|
+ }
|
|
|
+ }), error);
|
|
|
+ });
|
|
|
+
|
|
|
+ selectDB();
|
|
|
+};
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ */
|
|
|
+NotionClient.prototype.logout = function()
|
|
|
+{
|
|
|
+ //Send to server to clear token cookie
|
|
|
+ this.executeRequest('/removeToken', null, 'GET', function(){}, function(){});
|
|
|
+ this.setUser(null);
|
|
|
+ _token = null;
|
|
|
+};
|
|
|
+
|
|
|
+})();
|