From 25c6627368d583e0721390e20a054b2263eb3bdb Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Tue, 24 Nov 2015 13:06:50 -0600
Subject: [PATCH 1/8] [url shortener] initial prototype
---
src/plugins/kibana/public/dashboard/index.js | 27 ++++---
.../public/dashboard/partials/share.html | 5 +-
.../public/discover/controllers/discover.js | 3 +-
src/plugins/kibana/public/discover/index.html | 10 +++
.../discover/partials/share_search.html | 22 ++++++
src/plugins/kibana/public/goto/index.js | 22 ++++++
.../kibana/public/visualize/editor/editor.js | 16 ++--
.../public/visualize/editor/panels/share.html | 5 +-
src/server/http/index.js | 21 +++++
src/server/http/urlLookup.js | 77 +++++++++++++++++++
src/ui/public/directives/config.js | 2 +
src/ui/public/share/index.html | 39 ++++++++++
src/ui/public/share/index.js | 57 ++++++++++++++
src/ui/public/share/url_shortener.js | 27 +++++++
14 files changed, 310 insertions(+), 23 deletions(-)
create mode 100644 src/plugins/kibana/public/discover/partials/share_search.html
create mode 100644 src/plugins/kibana/public/goto/index.js
create mode 100644 src/server/http/urlLookup.js
create mode 100644 src/ui/public/share/index.html
create mode 100644 src/ui/public/share/index.js
create mode 100644 src/ui/public/share/url_shortener.js
diff --git a/src/plugins/kibana/public/dashboard/index.js b/src/plugins/kibana/public/dashboard/index.js
index 45e247b498755..f55e8b96371cc 100644
--- a/src/plugins/kibana/public/dashboard/index.js
+++ b/src/plugins/kibana/public/dashboard/index.js
@@ -10,6 +10,7 @@ define(function (require) {
require('ui/config');
require('ui/notify');
require('ui/typeahead');
+ require('ui/share');
require('plugins/kibana/dashboard/directives/grid');
require('plugins/kibana/dashboard/components/panel/panel');
@@ -25,7 +26,8 @@ define(function (require) {
'kibana/courier',
'kibana/config',
'kibana/notify',
- 'kibana/typeahead'
+ 'kibana/typeahead',
+ 'kibana/share'
]);
require('ui/routes')
@@ -90,6 +92,7 @@ define(function (require) {
var $uiState = $scope.uiState = $state.makeStateful('uiState');
$scope.$watchCollection('state.options', function (newVal, oldVal) {
+ //console.log('watch state.options');
if (!angular.equals(newVal, oldVal)) $state.save();
});
$scope.$watch('state.options.darkTheme', setDarkTheme);
@@ -154,6 +157,7 @@ define(function (require) {
}
function setDarkTheme(enabled) {
+ //console.log('setDarkTheme');
var theme = Boolean(enabled) ? 'theme-dark' : 'theme-light';
chrome.removeApplicationClass(['theme-dark', 'theme-light']);
chrome.addApplicationClass(theme);
@@ -161,6 +165,7 @@ define(function (require) {
// update root source when filters update
$scope.$listen(queryFilter, 'update', function () {
+ //console.log('queryFilter update');
updateQueryOnRootSource();
$state.save();
});
@@ -233,15 +238,17 @@ define(function (require) {
ui: $state.options,
save: $scope.save,
addVis: $scope.addVis,
- addSearch: $scope.addSearch,
- shareData: function () {
- return {
- link: $location.absUrl(),
- // This sucks, but seems like the cleanest way. Uhg.
- embed: ''
- };
- }
+ addSearch: $scope.addSearch
+ // ,
+ // shareData: function () {
+ // //console.log('this is being called.');
+ // return {
+ // link: $location.absUrl(),
+ // // This sucks, but seems like the cleanest way. Uhg.
+ // embed: ''
+ // };
+ // }
};
init();
diff --git a/src/plugins/kibana/public/dashboard/partials/share.html b/src/plugins/kibana/public/dashboard/partials/share.html
index bf34366604db1..79046da5db0b1 100644
--- a/src/plugins/kibana/public/dashboard/partials/share.html
+++ b/src/plugins/kibana/public/dashboard/partials/share.html
@@ -1,4 +1,5 @@
-
+
+
+
+
diff --git a/src/ui/public/share/index.js b/src/ui/public/share/index.js
new file mode 100644
index 0000000000000..a815bf6ee29b8
--- /dev/null
+++ b/src/ui/public/share/index.js
@@ -0,0 +1,57 @@
+define(function (require) {
+ const app = require('ui/modules').get('kibana/share');
+
+ app.directive('share', function (Private) {
+ const urlShortener = Private(require('./url_shortener'));
+
+ return {
+ restrict: 'E',
+ scope: { objectType: '@' },
+ template: require('ui/share/index.html'),
+ controller: function ($scope, $rootScope, $location, $http) {
+ $scope.shortUrlsLoading = false;
+
+ $scope.$watch('getUrl()', function (url) {
+ $scope.url = url;
+ $scope.embedUrl = url.replace('?', '?embed&');
+
+ //when the url changes we want to hide any generated short urls
+ $scope.shortenUrls = false;
+ $scope.shortUrl = undefined;
+ });
+
+ $scope.$watch('shortenUrls', enabled => {
+ if (!!enabled) {
+ if ($scope.shortUrl) {
+ $scope.shortUrlsLoading = false;
+ } else {
+ $scope.shortUrlsLoading = true;
+
+ const linkPromise = urlShortener.shortenUrl($scope.url)
+ .then(shortUrl => {
+ $scope.shortUrl = shortUrl;
+ });
+
+ const embedPromise = urlShortener.shortenUrl($scope.embedUrl)
+ .then(shortUrl => {
+ $scope.shortEmbedUrl = shortUrl;
+ });
+
+ Promise.all([linkPromise, embedPromise])
+ .then(() => {
+ $scope.shortUrlsLoading = false;
+ })
+ .catch(err => {
+ $scope.shortenUrls = false;
+ });
+ }
+ }
+ });
+
+ $scope.getUrl = function () {
+ return $location.absUrl();
+ };
+ }
+ };
+ });
+});
diff --git a/src/ui/public/share/url_shortener.js b/src/ui/public/share/url_shortener.js
new file mode 100644
index 0000000000000..304e30b3456d0
--- /dev/null
+++ b/src/ui/public/share/url_shortener.js
@@ -0,0 +1,27 @@
+define(function (require) {
+ return function createUrlShortener(Notifier, $http, $location) {
+ const notify = new Notifier({
+ location: 'Url Shortener'
+ });
+ const baseUrl = `${$location.protocol()}://${$location.host()}:${$location.port()}`;
+
+ async function shortenUrl(url) {
+ const relativeUrl = url.replace(baseUrl, '');
+
+ var formData = { url: relativeUrl };
+
+ try {
+ const result = await $http.post('/shorten', formData);
+
+ return `${baseUrl}/goto/${result.data}`;
+ } catch (err) {
+ notify.error(err);
+ throw err;
+ }
+ }
+
+ return {
+ shortenUrl
+ };
+ };
+});
From 5783f3135cbe91ec0944c5f407779aa091420cb4 Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Tue, 24 Nov 2015 16:35:12 -0600
Subject: [PATCH 2/8] [url shortener] modified to use hash
---
src/plugins/kibana/public/dashboard/index.js | 16 +--
.../public/dashboard/partials/share.html | 21 ----
.../public/discover/controllers/discover.js | 1 +
.../discover/partials/share_search.html | 21 ----
src/plugins/kibana/public/goto/index.js | 22 ----
.../kibana/public/visualize/editor/editor.js | 10 +-
.../public/visualize/editor/panels/share.html | 22 ----
src/server/http/index.js | 1 -
src/server/http/urlLookup.js | 112 +++++++++++-------
src/ui/public/directives/config.js | 2 -
src/ui/public/share/index.js | 2 +-
src/ui/public/share/url_shortener.js | 3 +-
12 files changed, 72 insertions(+), 161 deletions(-)
delete mode 100644 src/plugins/kibana/public/goto/index.js
diff --git a/src/plugins/kibana/public/dashboard/index.js b/src/plugins/kibana/public/dashboard/index.js
index f55e8b96371cc..d3464adca65be 100644
--- a/src/plugins/kibana/public/dashboard/index.js
+++ b/src/plugins/kibana/public/dashboard/index.js
@@ -26,8 +26,7 @@ define(function (require) {
'kibana/courier',
'kibana/config',
'kibana/notify',
- 'kibana/typeahead',
- 'kibana/share'
+ 'kibana/typeahead'
]);
require('ui/routes')
@@ -92,7 +91,6 @@ define(function (require) {
var $uiState = $scope.uiState = $state.makeStateful('uiState');
$scope.$watchCollection('state.options', function (newVal, oldVal) {
- //console.log('watch state.options');
if (!angular.equals(newVal, oldVal)) $state.save();
});
$scope.$watch('state.options.darkTheme', setDarkTheme);
@@ -157,7 +155,6 @@ define(function (require) {
}
function setDarkTheme(enabled) {
- //console.log('setDarkTheme');
var theme = Boolean(enabled) ? 'theme-dark' : 'theme-light';
chrome.removeApplicationClass(['theme-dark', 'theme-light']);
chrome.addApplicationClass(theme);
@@ -165,7 +162,6 @@ define(function (require) {
// update root source when filters update
$scope.$listen(queryFilter, 'update', function () {
- //console.log('queryFilter update');
updateQueryOnRootSource();
$state.save();
});
@@ -239,16 +235,6 @@ define(function (require) {
save: $scope.save,
addVis: $scope.addVis,
addSearch: $scope.addSearch
- // ,
- // shareData: function () {
- // //console.log('this is being called.');
- // return {
- // link: $location.absUrl(),
- // // This sucks, but seems like the cleanest way. Uhg.
- // embed: ''
- // };
- // }
};
init();
diff --git a/src/plugins/kibana/public/dashboard/partials/share.html b/src/plugins/kibana/public/dashboard/partials/share.html
index 79046da5db0b1..cf9fc6898b4f2 100644
--- a/src/plugins/kibana/public/dashboard/partials/share.html
+++ b/src/plugins/kibana/public/dashboard/partials/share.html
@@ -1,22 +1 @@
-
diff --git a/src/plugins/kibana/public/discover/controllers/discover.js b/src/plugins/kibana/public/discover/controllers/discover.js
index e69f9065736e2..a457131965d30 100644
--- a/src/plugins/kibana/public/discover/controllers/discover.js
+++ b/src/plugins/kibana/public/discover/controllers/discover.js
@@ -20,6 +20,7 @@ define(function (require) {
require('ui/state_management/app_state');
require('ui/timefilter');
require('ui/highlight/highlight_tags');
+ require('ui/share');
var app = require('ui/modules').get('apps/discover', [
'kibana/notify',
diff --git a/src/plugins/kibana/public/discover/partials/share_search.html b/src/plugins/kibana/public/discover/partials/share_search.html
index 6b878b6c8c7f4..3870634f84832 100644
--- a/src/plugins/kibana/public/discover/partials/share_search.html
+++ b/src/plugins/kibana/public/discover/partials/share_search.html
@@ -1,22 +1 @@
-
diff --git a/src/plugins/kibana/public/goto/index.js b/src/plugins/kibana/public/goto/index.js
deleted file mode 100644
index 9c1aea43172de..0000000000000
--- a/src/plugins/kibana/public/goto/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-define(function (require) {
- var angular = require('angular');
-
- require('ui/routes')
- .when('/goto/:id', {
- template: require('plugins/kibana/dashboard/index.html'),
- resolve: {
- dash: function (savedDashboards, Notifier, $route, $location, courier) {
- return savedDashboards.get($route.current.params.id)
- .catch(courier.redirectWhenMissing({
- 'dashboard' : '/dashboard'
- }));
- }
- }
- });
-
- require('ui/routes')
- .when('/visualize', {
- redirectTo: '/visualize/step/1'
- });
-
-});
diff --git a/src/plugins/kibana/public/visualize/editor/editor.js b/src/plugins/kibana/public/visualize/editor/editor.js
index 92f4e2f2ea88b..9f7c628493c0e 100644
--- a/src/plugins/kibana/public/visualize/editor/editor.js
+++ b/src/plugins/kibana/public/visualize/editor/editor.js
@@ -6,6 +6,7 @@ define(function (require) {
require('ui/visualize');
require('ui/collapsible_sidebar');
+ require('ui/share');
require('ui/routes')
.when('/visualize/create', {
@@ -234,15 +235,6 @@ define(function (require) {
}, notify.fatal);
};
- // $scope.shareData = function () {
- // return {
- // link: $location.absUrl(),
- // // This sucks, but seems like the cleanest way. Uhg.
- // embed: ''
- // };
- // };
-
$scope.unlink = function () {
if (!$state.linked) return;
diff --git a/src/plugins/kibana/public/visualize/editor/panels/share.html b/src/plugins/kibana/public/visualize/editor/panels/share.html
index 2292d1eb311c0..0a3cda5e13b24 100644
--- a/src/plugins/kibana/public/visualize/editor/panels/share.html
+++ b/src/plugins/kibana/public/visualize/editor/panels/share.html
@@ -1,23 +1 @@
-
diff --git a/src/server/http/index.js b/src/server/http/index.js
index 9c7fcfab30f34..52a79d1450584 100644
--- a/src/server/http/index.js
+++ b/src/server/http/index.js
@@ -31,7 +31,6 @@ module.exports = function (kbnServer, server, config) {
server.connection(connectionOptions);
-
// provide a simple way to expose static directories
server.decorate('server', 'exposeStaticDir', function (routePath, dirPath) {
this.route({
diff --git a/src/server/http/urlLookup.js b/src/server/http/urlLookup.js
index e7c8f03931f6c..18e094a08462a 100644
--- a/src/server/http/urlLookup.js
+++ b/src/server/http/urlLookup.js
@@ -17,61 +17,83 @@ export default function (server) {
}
});
} catch (err) {
- console.log(err);
- //swallow errors. We don't care if there is no update.
+ console.log('Error updating url metadata', err);
+ //swallow errors. It isn't critical if there is no update.
}
}
- return {
- async generateUrlId(url) {
- const urlId = await new Promise((resolve, reject) => {
- const client = server.plugins.elasticsearch.client;
+ async function getUrlDoc(urlId) {
+ const urlDoc = await new Promise((resolve, reject) => {
+ const client = server.plugins.elasticsearch.client;
- // const urlId = crypto.createHash('md5')
- // .update(url)
- // .digest('hex');
+ client.get({
+ index: '.kibana',
+ type: 'url',
+ id: urlId
+ })
+ .then(response => {
+ resolve(response);
+ })
+ .catch(err => {
+ resolve();
+ });
+ });
- client.index({
- index: '.kibana',
- type: 'url',
- body: {
- url,
- 'access-count': 0,
- 'create-date': new Date(),
- 'access-date': new Date()
- }
- })
- .then(response => {
- const urlId = response._id;
- resolve(urlId);
- })
- .catch(err => {
- reject(err);
- });
+ return urlDoc;
+ }
+
+ async function createUrlDoc(url, urlId) {
+ const newUrlId = await new Promise((resolve, reject) => {
+ const client = server.plugins.elasticsearch.client;
+
+ client.index({
+ index: '.kibana',
+ type: 'url',
+ id: urlId,
+ body: {
+ url,
+ 'access-count': 0,
+ 'create-date': new Date(),
+ 'access-date': new Date()
+ }
+ })
+ .then(response => {
+ resolve(response._id);
+ })
+ .catch(err => {
+ reject(err);
});
+ });
+
+ return newUrlId;
+ }
+
+ function createUrlId(url) {
+ const urlId = crypto.createHash('md5')
+ .update(url)
+ .digest('hex');
+
+ return urlId;
+ }
- return urlId;
+ return {
+ async generateUrlId(url) {
+ const urlId = createUrlId(url);
+
+ const urlDoc = await getUrlDoc(urlId);
+ if (urlDoc) return urlId;
+
+ return createUrlDoc(url, urlId);
},
async getUrl(urlId) {
- const url = await new Promise((resolve, reject) => {
- const client = server.plugins.elasticsearch.client;
-
- client.get({
- index: '.kibana',
- type: 'url',
- id: urlId
- })
- .then(response => {
- const url = response._source.url;
- updateMetadata(urlId, response);
- resolve(url);
- })
- .catch(err => {
- resolve('/');
- });
- });
+ try {
+ const urlDoc = await getUrlDoc(urlId);
+ updateMetadata(urlId, urlDoc);
- return url;
+ return urlDoc._source.url;
+ } catch (err) {
+ return '/';
+ }
}
};
};
diff --git a/src/ui/public/directives/config.js b/src/ui/public/directives/config.js
index d02e99d7d0746..a8f69b28ca5e7 100644
--- a/src/ui/public/directives/config.js
+++ b/src/ui/public/directives/config.js
@@ -29,7 +29,6 @@ define(function (require) {
var tmpScope = $scope.$new();
$scope.$watch('configObject', function (newVal) {
- console.log('config watch');
$scope[attr.configObject] = $scope.configObject;
});
@@ -45,7 +44,6 @@ define(function (require) {
'configSubmit',
'configTemplate.current || configTemplate'
], function () {
- console.log('config watchMulti');
var tmpl = $scope.configTemplate;
if (tmpl instanceof ConfigTemplate) {
tmpl = tmpl.toString();
diff --git a/src/ui/public/share/index.js b/src/ui/public/share/index.js
index a815bf6ee29b8..1e587a0fd7452 100644
--- a/src/ui/public/share/index.js
+++ b/src/ui/public/share/index.js
@@ -1,5 +1,5 @@
define(function (require) {
- const app = require('ui/modules').get('kibana/share');
+ const app = require('ui/modules').get('kibana');
app.directive('share', function (Private) {
const urlShortener = Private(require('./url_shortener'));
diff --git a/src/ui/public/share/url_shortener.js b/src/ui/public/share/url_shortener.js
index 304e30b3456d0..98411fd2bcd6c 100644
--- a/src/ui/public/share/url_shortener.js
+++ b/src/ui/public/share/url_shortener.js
@@ -7,8 +7,7 @@ define(function (require) {
async function shortenUrl(url) {
const relativeUrl = url.replace(baseUrl, '');
-
- var formData = { url: relativeUrl };
+ const formData = { url: relativeUrl };
try {
const result = await $http.post('/shorten', formData);
From 7fcef6b7caac6d8fcd9cb49c83c7d8987c3ccf63 Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Mon, 30 Nov 2015 14:47:20 -0600
Subject: [PATCH 3/8] Addressed how modules were defined
---
src/server/http/index.js | 6 +-
.../{urlLookup.js => short_url_lookup.js} | 12 +-
src/ui/public/share/index.js | 106 +++++++++---------
src/ui/public/share/url_shortener.js | 38 +++----
4 files changed, 79 insertions(+), 83 deletions(-)
rename src/server/http/{urlLookup.js => short_url_lookup.js} (89%)
diff --git a/src/server/http/index.js b/src/server/http/index.js
index 52a79d1450584..4208d7f01eaa8 100644
--- a/src/server/http/index.js
+++ b/src/server/http/index.js
@@ -10,7 +10,7 @@ module.exports = function (kbnServer, server, config) {
server = kbnServer.server = new Hapi.Server();
- const urlLookup = require('./urlLookup')(server);
+ const shortUrlLookup = require('./short_url_lookup')(server);
// Create a new connection
var connectionOptions = {
@@ -128,7 +128,7 @@ module.exports = function (kbnServer, server, config) {
method: 'GET',
path: '/goto/{urlId}',
handler: async function (request, reply) {
- const url = await urlLookup.getUrl(request.params.urlId);
+ const url = await shortUrlLookup.getUrl(request.params.urlId);
reply().redirect(url);
}
});
@@ -137,7 +137,7 @@ module.exports = function (kbnServer, server, config) {
method: 'POST',
path: '/shorten',
handler: async function (request, reply) {
- const urlId = await urlLookup.generateUrlId(request.payload.url);
+ const urlId = await shortUrlLookup.generateUrlId(request.payload.url);
reply(urlId);
}
});
diff --git a/src/server/http/urlLookup.js b/src/server/http/short_url_lookup.js
similarity index 89%
rename from src/server/http/urlLookup.js
rename to src/server/http/short_url_lookup.js
index 18e094a08462a..a67accada2ca8 100644
--- a/src/server/http/urlLookup.js
+++ b/src/server/http/short_url_lookup.js
@@ -11,8 +11,8 @@ export default function (server) {
id: urlId,
body: {
doc: {
- 'access-date': new Date(),
- 'access-count': urlDoc._source['access-count'] + 1
+ 'accessDate': new Date(),
+ 'accessCount': urlDoc._source.accessCount + 1
}
}
});
@@ -35,7 +35,7 @@ export default function (server) {
resolve(response);
})
.catch(err => {
- resolve();
+ reject();
});
});
@@ -52,9 +52,9 @@ export default function (server) {
id: urlId,
body: {
url,
- 'access-count': 0,
- 'create-date': new Date(),
- 'access-date': new Date()
+ 'accessCount': 0,
+ 'createDate': new Date(),
+ 'accessDate': new Date()
}
})
.then(response => {
diff --git a/src/ui/public/share/index.js b/src/ui/public/share/index.js
index 1e587a0fd7452..5cb9cd42a81b8 100644
--- a/src/ui/public/share/index.js
+++ b/src/ui/public/share/index.js
@@ -1,57 +1,55 @@
-define(function (require) {
- const app = require('ui/modules').get('kibana');
-
- app.directive('share', function (Private) {
- const urlShortener = Private(require('./url_shortener'));
-
- return {
- restrict: 'E',
- scope: { objectType: '@' },
- template: require('ui/share/index.html'),
- controller: function ($scope, $rootScope, $location, $http) {
- $scope.shortUrlsLoading = false;
-
- $scope.$watch('getUrl()', function (url) {
- $scope.url = url;
- $scope.embedUrl = url.replace('?', '?embed&');
-
- //when the url changes we want to hide any generated short urls
- $scope.shortenUrls = false;
- $scope.shortUrl = undefined;
- });
-
- $scope.$watch('shortenUrls', enabled => {
- if (!!enabled) {
- if ($scope.shortUrl) {
+const app = require('ui/modules').get('kibana');
+
+app.directive('share', function (Private) {
+ const urlShortener = Private(require('./url_shortener'));
+
+ return {
+ restrict: 'E',
+ scope: { objectType: '@' },
+ template: require('ui/share/index.html'),
+ controller: function ($scope, $rootScope, $location, $http) {
+ $scope.shortUrlsLoading = false;
+
+ $scope.$watch('getUrl()', function (url) {
+ $scope.url = url;
+ $scope.embedUrl = url.replace('?', '?embed&');
+
+ //when the url changes we want to hide any generated short urls
+ $scope.shortenUrls = false;
+ $scope.shortUrl = undefined;
+ });
+
+ $scope.$watch('shortenUrls', enabled => {
+ if (!!enabled) {
+ if ($scope.shortUrl) {
+ $scope.shortUrlsLoading = false;
+ } else {
+ $scope.shortUrlsLoading = true;
+
+ const linkPromise = urlShortener.shortenUrl($scope.url)
+ .then(shortUrl => {
+ $scope.shortUrl = shortUrl;
+ });
+
+ const embedPromise = urlShortener.shortenUrl($scope.embedUrl)
+ .then(shortUrl => {
+ $scope.shortEmbedUrl = shortUrl;
+ });
+
+ Promise.all([linkPromise, embedPromise])
+ .then(() => {
$scope.shortUrlsLoading = false;
- } else {
- $scope.shortUrlsLoading = true;
-
- const linkPromise = urlShortener.shortenUrl($scope.url)
- .then(shortUrl => {
- $scope.shortUrl = shortUrl;
- });
-
- const embedPromise = urlShortener.shortenUrl($scope.embedUrl)
- .then(shortUrl => {
- $scope.shortEmbedUrl = shortUrl;
- });
-
- Promise.all([linkPromise, embedPromise])
- .then(() => {
- $scope.shortUrlsLoading = false;
- })
- .catch(err => {
- $scope.shortenUrls = false;
- });
- }
+ })
+ .catch(err => {
+ $scope.shortenUrls = false;
+ });
}
- });
-
- $scope.getUrl = function () {
- return $location.absUrl();
- };
- }
- };
- });
+ }
+ });
+
+ $scope.getUrl = function () {
+ return $location.absUrl();
+ };
+ }
+ };
});
diff --git a/src/ui/public/share/url_shortener.js b/src/ui/public/share/url_shortener.js
index 98411fd2bcd6c..3e29500d8d2f0 100644
--- a/src/ui/public/share/url_shortener.js
+++ b/src/ui/public/share/url_shortener.js
@@ -1,26 +1,24 @@
-define(function (require) {
- return function createUrlShortener(Notifier, $http, $location) {
- const notify = new Notifier({
- location: 'Url Shortener'
- });
- const baseUrl = `${$location.protocol()}://${$location.host()}:${$location.port()}`;
+export default function createUrlShortener(Notifier, $http, $location) {
+ const notify = new Notifier({
+ location: 'Url Shortener'
+ });
+ const baseUrl = `${$location.protocol()}://${$location.host()}:${$location.port()}`;
- async function shortenUrl(url) {
- const relativeUrl = url.replace(baseUrl, '');
- const formData = { url: relativeUrl };
+ async function shortenUrl(url) {
+ const relativeUrl = url.replace(baseUrl, '');
+ const formData = { url: relativeUrl };
- try {
- const result = await $http.post('/shorten', formData);
+ try {
+ const result = await $http.post('/shorten', formData);
- return `${baseUrl}/goto/${result.data}`;
- } catch (err) {
- notify.error(err);
- throw err;
- }
+ return `${baseUrl}/goto/${result.data}`;
+ } catch (err) {
+ notify.error(err);
+ throw err;
}
+ }
- return {
- shortenUrl
- };
+ return {
+ shortenUrl
};
-});
+};
From cef5afd4d8cf5611f674bad4e2e1c2812b3bcc8e Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Wed, 2 Dec 2015 12:05:00 -0600
Subject: [PATCH 4/8] [url shortener] Can now share urls without app state in
url
---
.../public/dashboard/partials/share.html | 5 +-
.../discover/partials/share_search.html | 5 +-
.../public/visualize/editor/panels/share.html | 5 +-
src/server/http/short_url_lookup.js | 6 ++-
src/ui/public/share/index.html | 9 +++-
src/ui/public/share/index.js | 51 ++++++++++++++++---
6 files changed, 68 insertions(+), 13 deletions(-)
diff --git a/src/plugins/kibana/public/dashboard/partials/share.html b/src/plugins/kibana/public/dashboard/partials/share.html
index cf9fc6898b4f2..046acbb5c95b8 100644
--- a/src/plugins/kibana/public/dashboard/partials/share.html
+++ b/src/plugins/kibana/public/dashboard/partials/share.html
@@ -1 +1,4 @@
-
+
+
diff --git a/src/plugins/kibana/public/discover/partials/share_search.html b/src/plugins/kibana/public/discover/partials/share_search.html
index 3870634f84832..8e41617ae1f07 100644
--- a/src/plugins/kibana/public/discover/partials/share_search.html
+++ b/src/plugins/kibana/public/discover/partials/share_search.html
@@ -1 +1,4 @@
-
+
+
diff --git a/src/plugins/kibana/public/visualize/editor/panels/share.html b/src/plugins/kibana/public/visualize/editor/panels/share.html
index 0a3cda5e13b24..016109cfff6f5 100644
--- a/src/plugins/kibana/public/visualize/editor/panels/share.html
+++ b/src/plugins/kibana/public/visualize/editor/panels/share.html
@@ -1 +1,4 @@
-
+
+
diff --git a/src/server/http/short_url_lookup.js b/src/server/http/short_url_lookup.js
index a67accada2ca8..d312ac12fba83 100644
--- a/src/server/http/short_url_lookup.js
+++ b/src/server/http/short_url_lookup.js
@@ -17,7 +17,7 @@ export default function (server) {
}
});
} catch (err) {
- console.log('Error updating url metadata', err);
+ console.log('Warning: Error updating url metadata', err);
//swallow errors. It isn't critical if there is no update.
}
}
@@ -35,7 +35,7 @@ export default function (server) {
resolve(response);
})
.catch(err => {
- reject();
+ resolve();
});
});
@@ -88,6 +88,8 @@ export default function (server) {
async getUrl(urlId) {
try {
const urlDoc = await getUrlDoc(urlId);
+ if (!urlDoc) throw new Error('Requested shortened url does note exist in kibana index');
+
updateMetadata(urlId, urlDoc);
return urlDoc._source.url;
diff --git a/src/ui/public/share/index.html b/src/ui/public/share/index.html
index 022adc462812e..9d920b8ec1e1c 100644
--- a/src/ui/public/share/index.html
+++ b/src/ui/public/share/index.html
@@ -1,4 +1,11 @@
diff --git a/src/ui/public/share/index.js b/src/ui/public/share/index.js
index 08c06abbedae8..254f3c9e0b1ad 100644
--- a/src/ui/public/share/index.js
+++ b/src/ui/public/share/index.js
@@ -1,6 +1,7 @@
const app = require('ui/modules').get('kibana');
const _ = require('lodash');
const { parse } = require('querystring');
+const angular = require('angular');
app.directive('share', function (Private) {
const urlShortener = Private(require('./url_shortener'));
@@ -9,10 +10,12 @@ app.directive('share', function (Private) {
restrict: 'E',
scope: {
objectType: '@',
- objectId: '@'
+ objectId: '@',
+ setAllowEmbed: '&?allowEmbed'
},
template: require('ui/share/index.html'),
controller: function ($scope, $rootScope, $location) {
+ $scope.allowEmbed = $scope.setAllowEmbed ? $scope.setAllowEmbed() : true;
$scope.shortUrlsLoading = false;
function updateUrl(url) {
From 0fb14507740a9a3ef943eea9aa5bef7cb818b7d3 Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Fri, 11 Dec 2015 09:17:54 -0600
Subject: [PATCH 6/8] [url shortener] reorganized code, added clipboard.js
support
---
package.json | 1 +
src/ui/public/share/directives/share.js | 16 +++
.../share/directives/share_object_url.js | 86 ++++++++++++++++
src/ui/public/share/index.html | 46 ---------
src/ui/public/share/index.js | 97 +------------------
src/ui/public/share/lib/build_query_string.js | 9 ++
.../share/lib/remove_query_string_value.js | 16 +++
.../public/share/{ => lib}/url_shortener.js | 0
src/ui/public/share/styles/index.less | 21 ++++
src/ui/public/share/views/share.html | 32 ++++++
.../public/share/views/share_object_url.html | 21 ++++
11 files changed, 204 insertions(+), 141 deletions(-)
create mode 100644 src/ui/public/share/directives/share.js
create mode 100644 src/ui/public/share/directives/share_object_url.js
delete mode 100644 src/ui/public/share/index.html
create mode 100644 src/ui/public/share/lib/build_query_string.js
create mode 100644 src/ui/public/share/lib/remove_query_string_value.js
rename src/ui/public/share/{ => lib}/url_shortener.js (100%)
create mode 100644 src/ui/public/share/styles/index.less
create mode 100644 src/ui/public/share/views/share.html
create mode 100644 src/ui/public/share/views/share_object_url.html
diff --git a/package.json b/package.json
index 82d78b0300578..d312662c5514a 100644
--- a/package.json
+++ b/package.json
@@ -82,6 +82,7 @@
"bootstrap": "3.3.5",
"brace": "0.5.1",
"bunyan": "1.4.0",
+ "clipboard": "1.5.5",
"commander": "2.8.1",
"css-loader": "0.17.0",
"d3": "3.5.6",
diff --git a/src/ui/public/share/directives/share.js b/src/ui/public/share/directives/share.js
new file mode 100644
index 0000000000000..49ebb95afba34
--- /dev/null
+++ b/src/ui/public/share/directives/share.js
@@ -0,0 +1,16 @@
+const app = require('ui/modules').get('kibana');
+
+app.directive('share', function () {
+ return {
+ restrict: 'E',
+ scope: {
+ objectType: '@',
+ objectId: '@',
+ setAllowEmbed: '&?allowEmbed'
+ },
+ template: require('ui/share/views/share.html'),
+ controller: function ($scope) {
+ $scope.allowEmbed = $scope.setAllowEmbed ? $scope.setAllowEmbed() : true;
+ }
+ };
+});
diff --git a/src/ui/public/share/directives/share_object_url.js b/src/ui/public/share/directives/share_object_url.js
new file mode 100644
index 0000000000000..6bd0d7053820b
--- /dev/null
+++ b/src/ui/public/share/directives/share_object_url.js
@@ -0,0 +1,86 @@
+const app = require('ui/modules').get('kibana');
+const Clipboard = require('clipboard');
+const removeQueryStringValue = require('../lib/remove_query_string_value');
+
+require('../styles/index.less');
+
+app.directive('shareObjectUrl', function (Private, Notifier) {
+ const urlShortener = Private(require('../lib/url_shortener'));
+
+ return {
+ restrict: 'E',
+ scope: {
+ getShareAsEmbed: '&shareAsEmbed',
+ stripAppState: '='
+ },
+ template: require('ui/share/views/share_object_url.html'),
+ link: function ($scope, $el) {
+ const notify = new Notifier({
+ location: `Share ${$scope.$parent.objectType}`
+ });
+
+ $scope.textbox = $el.find('input.url')[0];
+ $scope.clipboardButton = $el.find('button.clipboard-button')[0];
+
+ const clipboard = new Clipboard($scope.clipboardButton, {
+ target: function (trigger) {
+ return $scope.textbox;
+ }
+ });
+
+ clipboard.on('success', function (e) {
+ notify.info('URL copied to clipboard.');
+ e.clearSelection();
+ });
+
+ clipboard.on('error', function (e) {
+ notify.info('URL selected. Press Ctrl+C to copy.');
+ });
+
+ $scope.clipboard = clipboard;
+ },
+ controller: function ($scope, $location) {
+ function updateUrl(url) {
+ $scope.url = url;
+
+ if ($scope.shareAsEmbed) {
+ $scope.formattedUrl = ``;
+ } else {
+ $scope.formattedUrl = $scope.url;
+ }
+
+ $scope.shortGenerated = false;
+ }
+
+ $scope.shareAsEmbed = $scope.getShareAsEmbed();
+
+ $scope.generateShortUrl = function () {
+ if ($scope.shortGenerated) return;
+
+ $scope.generating = true;
+ urlShortener.shortenUrl($scope.url)
+ .then(shortUrl => {
+ updateUrl(shortUrl);
+ $scope.shortGenerated = true;
+ $scope.generating = false;
+ });
+ };
+
+ $scope.getUrl = function () {
+ return $location.absUrl();
+ };
+
+ $scope.$watch('getUrl()', updateUrl);
+
+ $scope.$watch('stripAppState', function (enabled) {
+ const currentUrl = $scope.getUrl();
+ if (enabled) {
+ let newUrl = removeQueryStringValue(currentUrl, '_a');
+ updateUrl(newUrl);
+ } else {
+ updateUrl(currentUrl);
+ }
+ });
+ }
+ };
+});
diff --git a/src/ui/public/share/index.html b/src/ui/public/share/index.html
deleted file mode 100644
index 8ef8688d8b9e6..0000000000000
--- a/src/ui/public/share/index.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
-
- Link to saved {{objectType}}
- By selecting this option, future changes to this saved {{objectType}} will be reflected in the shared view. Note: Shared URLs always include globally persisted state such as time picker and auto refresh.
-
-
-
-
- Shorten URLs
-
-
-
-
diff --git a/src/ui/public/share/index.js b/src/ui/public/share/index.js
index 254f3c9e0b1ad..2dec91dcc725d 100644
--- a/src/ui/public/share/index.js
+++ b/src/ui/public/share/index.js
@@ -1,95 +1,2 @@
-const app = require('ui/modules').get('kibana');
-const _ = require('lodash');
-const { parse } = require('querystring');
-const angular = require('angular');
-
-app.directive('share', function (Private) {
- const urlShortener = Private(require('./url_shortener'));
-
- return {
- restrict: 'E',
- scope: {
- objectType: '@',
- objectId: '@',
- setAllowEmbed: '&?allowEmbed'
- },
- template: require('ui/share/index.html'),
- controller: function ($scope, $rootScope, $location) {
- $scope.allowEmbed = $scope.setAllowEmbed ? $scope.setAllowEmbed() : true;
- $scope.shortUrlsLoading = false;
-
- function updateUrl(url) {
- $scope.url = url;
- $scope.embedUrl = url.replace('?', '?embed&');
-
- //when the url changes we want to hide any generated short urls
- $scope.shortenUrls = false;
- $scope.shortUrl = undefined;
- }
-
- function buildQueryString(data) {
- var result = [];
- _.forOwn(data, (value, key) => {
- result.push(`${key}=${value}`);
- });
- return result.join('&');
- }
-
- function removeAppState(url) {
- let index = url.indexOf('?');
- if (index === -1) return url;
-
- let base = url.substring(0, index);
- let qs = url.substring(index + 1);
-
- let qsParts = parse(qs);
- delete qsParts._a;
- qs = buildQueryString(qsParts);
-
- return `${base}?${qs}`;
- }
-
- $scope.getUrl = function () {
- return $location.absUrl();
- };
-
- $scope.$watch('getUrl()', updateUrl);
-
- $scope.$watch('ignoreState', enabled => {
- if (enabled) {
- updateUrl(removeAppState($scope.url));
- } else {
- updateUrl($scope.getUrl());
- }
- });
-
- $scope.$watch('shortenUrls', enabled => {
- if (!!enabled) {
- if ($scope.shortUrl) {
- $scope.shortUrlsLoading = false;
- } else {
- $scope.shortUrlsLoading = true;
-
- const linkPromise = urlShortener.shortenUrl($scope.url)
- .then(shortUrl => {
- $scope.shortUrl = shortUrl;
- });
-
- const embedPromise = urlShortener.shortenUrl($scope.embedUrl)
- .then(shortUrl => {
- $scope.shortEmbedUrl = shortUrl;
- });
-
- Promise.all([linkPromise, embedPromise])
- .then(() => {
- $scope.shortUrlsLoading = false;
- })
- .catch(err => {
- $scope.shortenUrls = false;
- });
- }
- }
- });
- }
- };
-});
+require('./directives/share');
+require('./directives/share_object_url');
diff --git a/src/ui/public/share/lib/build_query_string.js b/src/ui/public/share/lib/build_query_string.js
new file mode 100644
index 0000000000000..35c1c61055b6e
--- /dev/null
+++ b/src/ui/public/share/lib/build_query_string.js
@@ -0,0 +1,9 @@
+const _ = require('lodash');
+
+export default function buildQueryString(data) {
+ var result = [];
+ _.forOwn(data, (value, key) => {
+ result.push(`${key}=${value}`);
+ });
+ return result.join('&');
+}
diff --git a/src/ui/public/share/lib/remove_query_string_value.js b/src/ui/public/share/lib/remove_query_string_value.js
new file mode 100644
index 0000000000000..7e9c7c2f2053f
--- /dev/null
+++ b/src/ui/public/share/lib/remove_query_string_value.js
@@ -0,0 +1,16 @@
+const buildQueryString = require('./build_query_string');
+const { parse } = require('querystring');
+
+export default function removeAppState(url, key) {
+ let index = url.indexOf('?');
+ if (index === -1) return url;
+
+ let base = url.substring(0, index);
+ let qs = url.substring(index + 1);
+
+ let qsParts = parse(qs);
+ delete qsParts[key];
+ qs = buildQueryString(qsParts);
+
+ return `${base}?${qs}`;
+}
diff --git a/src/ui/public/share/url_shortener.js b/src/ui/public/share/lib/url_shortener.js
similarity index 100%
rename from src/ui/public/share/url_shortener.js
rename to src/ui/public/share/lib/url_shortener.js
diff --git a/src/ui/public/share/styles/index.less b/src/ui/public/share/styles/index.less
new file mode 100644
index 0000000000000..5acb20bb3449a
--- /dev/null
+++ b/src/ui/public/share/styles/index.less
@@ -0,0 +1,21 @@
+share-object-url {
+ .input-group {
+ display: flex;
+
+ .clipboard-button {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ .shorten-button {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ .form-control.url {
+ cursor: text;
+ }
+ }
+}
diff --git a/src/ui/public/share/views/share.html b/src/ui/public/share/views/share.html
new file mode 100644
index 0000000000000..4c57e51287d05
--- /dev/null
+++ b/src/ui/public/share/views/share.html
@@ -0,0 +1,32 @@
+
+
+
+
+ Embed this {{objectType}}
+ Add to your html source. Note all clients must still be able to access kibana
+
+
+
+
+
+
+ Share a link
+
+
+
+
+
diff --git a/src/ui/public/share/views/share_object_url.html b/src/ui/public/share/views/share_object_url.html
new file mode 100644
index 0000000000000..6c1b1438e9e90
--- /dev/null
+++ b/src/ui/public/share/views/share_object_url.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
From e59750cad2de21de89f9d18b1a983022695ef9ef Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Fri, 11 Dec 2015 13:44:06 -0600
Subject: [PATCH 7/8] [url shortener] removed link-to-saved-object
functionality
---
.../share/directives/share_object_url.js | 16 +-------------
src/ui/public/share/lib/build_query_string.js | 9 --------
.../share/lib/remove_query_string_value.js | 16 --------------
src/ui/public/share/views/share.html | 21 ++-----------------
4 files changed, 3 insertions(+), 59 deletions(-)
delete mode 100644 src/ui/public/share/lib/build_query_string.js
delete mode 100644 src/ui/public/share/lib/remove_query_string_value.js
diff --git a/src/ui/public/share/directives/share_object_url.js b/src/ui/public/share/directives/share_object_url.js
index 6bd0d7053820b..93e6207293fa4 100644
--- a/src/ui/public/share/directives/share_object_url.js
+++ b/src/ui/public/share/directives/share_object_url.js
@@ -1,6 +1,5 @@
const app = require('ui/modules').get('kibana');
const Clipboard = require('clipboard');
-const removeQueryStringValue = require('../lib/remove_query_string_value');
require('../styles/index.less');
@@ -10,8 +9,7 @@ app.directive('shareObjectUrl', function (Private, Notifier) {
return {
restrict: 'E',
scope: {
- getShareAsEmbed: '&shareAsEmbed',
- stripAppState: '='
+ getShareAsEmbed: '&shareAsEmbed'
},
template: require('ui/share/views/share_object_url.html'),
link: function ($scope, $el) {
@@ -57,12 +55,10 @@ app.directive('shareObjectUrl', function (Private, Notifier) {
$scope.generateShortUrl = function () {
if ($scope.shortGenerated) return;
- $scope.generating = true;
urlShortener.shortenUrl($scope.url)
.then(shortUrl => {
updateUrl(shortUrl);
$scope.shortGenerated = true;
- $scope.generating = false;
});
};
@@ -71,16 +67,6 @@ app.directive('shareObjectUrl', function (Private, Notifier) {
};
$scope.$watch('getUrl()', updateUrl);
-
- $scope.$watch('stripAppState', function (enabled) {
- const currentUrl = $scope.getUrl();
- if (enabled) {
- let newUrl = removeQueryStringValue(currentUrl, '_a');
- updateUrl(newUrl);
- } else {
- updateUrl(currentUrl);
- }
- });
}
};
});
diff --git a/src/ui/public/share/lib/build_query_string.js b/src/ui/public/share/lib/build_query_string.js
deleted file mode 100644
index 35c1c61055b6e..0000000000000
--- a/src/ui/public/share/lib/build_query_string.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const _ = require('lodash');
-
-export default function buildQueryString(data) {
- var result = [];
- _.forOwn(data, (value, key) => {
- result.push(`${key}=${value}`);
- });
- return result.join('&');
-}
diff --git a/src/ui/public/share/lib/remove_query_string_value.js b/src/ui/public/share/lib/remove_query_string_value.js
deleted file mode 100644
index 7e9c7c2f2053f..0000000000000
--- a/src/ui/public/share/lib/remove_query_string_value.js
+++ /dev/null
@@ -1,16 +0,0 @@
-const buildQueryString = require('./build_query_string');
-const { parse } = require('querystring');
-
-export default function removeAppState(url, key) {
- let index = url.indexOf('?');
- if (index === -1) return url;
-
- let base = url.substring(0, index);
- let qs = url.substring(index + 1);
-
- let qsParts = parse(qs);
- delete qsParts[key];
- qs = buildQueryString(qsParts);
-
- return `${base}?${qs}`;
-}
diff --git a/src/ui/public/share/views/share.html b/src/ui/public/share/views/share.html
index 4c57e51287d05..5f7ffdd0a6797 100644
--- a/src/ui/public/share/views/share.html
+++ b/src/ui/public/share/views/share.html
@@ -1,32 +1,15 @@
-
Embed this {{objectType}}
Add to your html source. Note all clients must still be able to access kibana
-
-
+
Share a link
-
-
+
From 96b74040d99e92ac80e5439795c1e13eab1ee457 Mon Sep 17 00:00:00 2001
From: Jim Unger
Date: Thu, 17 Dec 2015 12:14:47 -0600
Subject: [PATCH 8/8] [url shortener] Added clipboard cleanup, fixed server
logging
---
src/server/http/short_url_lookup.js | 2 +-
src/ui/public/share/directives/share_object_url.js | 10 +++++++---
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/server/http/short_url_lookup.js b/src/server/http/short_url_lookup.js
index d312ac12fba83..4ced5e5d812a9 100644
--- a/src/server/http/short_url_lookup.js
+++ b/src/server/http/short_url_lookup.js
@@ -17,7 +17,7 @@ export default function (server) {
}
});
} catch (err) {
- console.log('Warning: Error updating url metadata', err);
+ server.log('Warning: Error updating url metadata', err);
//swallow errors. It isn't critical if there is no update.
}
}
diff --git a/src/ui/public/share/directives/share_object_url.js b/src/ui/public/share/directives/share_object_url.js
index 93e6207293fa4..ee65c86345d44 100644
--- a/src/ui/public/share/directives/share_object_url.js
+++ b/src/ui/public/share/directives/share_object_url.js
@@ -21,20 +21,24 @@ app.directive('shareObjectUrl', function (Private, Notifier) {
$scope.clipboardButton = $el.find('button.clipboard-button')[0];
const clipboard = new Clipboard($scope.clipboardButton, {
- target: function (trigger) {
+ target(trigger) {
return $scope.textbox;
}
});
- clipboard.on('success', function (e) {
+ clipboard.on('success', e => {
notify.info('URL copied to clipboard.');
e.clearSelection();
});
- clipboard.on('error', function (e) {
+ clipboard.on('error', () => {
notify.info('URL selected. Press Ctrl+C to copy.');
});
+ $scope.$on('$destroy', () => {
+ clipboard.destroy();
+ });
+
$scope.clipboard = clipboard;
},
controller: function ($scope, $location) {