From e931ea69287a03619d11072b40cc5d8705bea227 Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Sat, 23 Dec 2017 22:40:36 +0900 Subject: [PATCH 1/6] Add an unarchive dashboard button --- client/app/pages/dashboards/dashboard.html | 4 +++- client/app/pages/dashboards/dashboard.js | 18 +++++++++++++++++- redash/handlers/api.py | 4 +++- redash/handlers/dashboards.py | 17 +++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/client/app/pages/dashboards/dashboard.html b/client/app/pages/dashboards/dashboard.html index 9d564c6e36..d51058cdff 100644 --- a/client/app/pages/dashboards/dashboard.html +++ b/client/app/pages/dashboards/dashboard.html @@ -4,7 +4,9 @@

{{$ctrl.dashboard.name}} Unpublished - Archived +

diff --git a/client/app/pages/dashboards/dashboard.js b/client/app/pages/dashboards/dashboard.js index 236b6c3dba..8c8dd25939 100644 --- a/client/app/pages/dashboards/dashboard.js +++ b/client/app/pages/dashboards/dashboard.js @@ -4,7 +4,7 @@ import shareDashboardTemplate from './share-dashboard.html'; import './dashboard.less'; function DashboardCtrl( - $rootScope, $routeParams, $location, $timeout, $q, $uibModal, + $rootScope, $routeParams, $location, $timeout, $q, $uibModal, $http, Title, AlertDialog, Dashboard, currentUser, clientConfig, Events, dashboardGridOptions, toastr, ) { @@ -196,6 +196,22 @@ function DashboardCtrl( AlertDialog.open(title, message, confirm).then(archive); }; + this.unArchiveDashboard = () => { + const url = `api/dashboards/${this.dashboard.slug}/unarchive`; + const unarchive = () => { + Events.record('unarchive', 'dashboard', this.dashboard.id); + $http.patch(url).success(() => { + this.loadDashboard(); + }); + }; + + const title = 'Unarchive Dashboard'; + const message = `Are you sure you want to unarchive the "${this.dashboard.name}" dashboard?`; + const confirm = { class: 'btn-warning', title: 'Unarchive' }; + + AlertDialog.open(title, message, confirm).then(unarchive); + }; + this.showManagePermissionsModal = () => { $uibModal.open({ component: 'permissionsEditor', diff --git a/redash/handlers/api.py b/redash/handlers/api.py index f555246657..d0b375c31d 100644 --- a/redash/handlers/api.py +++ b/redash/handlers/api.py @@ -46,7 +46,9 @@ def json_representation(data, code, headers=None): api.add_org_resource(DashboardListResource, '/api/dashboards', endpoint='dashboards') api.add_org_resource(RecentDashboardsResource, '/api/dashboards/recent', endpoint='recent_dashboards') -api.add_org_resource(DashboardResource, '/api/dashboards/', endpoint='dashboard') +api.add_org_resource(DashboardResource, '/api/dashboards/', + '/api/dashboards//unarchive', + endpoint='dashboard') api.add_org_resource(PublicDashboardResource, '/api/dashboards/public/', endpoint='public_dashboard') api.add_org_resource(DashboardShareResource, '/api/dashboards//share', endpoint='dashboard_share') diff --git a/redash/handlers/dashboards.py b/redash/handlers/dashboards.py index 21564e05ee..33f09dfea0 100644 --- a/redash/handlers/dashboards.py +++ b/redash/handlers/dashboards.py @@ -166,6 +166,23 @@ def delete(self, dashboard_slug): models.db.session.commit() return d + @require_permission('edit_dashboard') + def patch(self, dashboard_slug): + """ + Unarchives a dashboard. + + :qparam string slug: Slug of dashboard to retrieve. + + Responds with the archived :ref:`dashboard `. + """ + dashboard = models.Dashboard.get_by_slug_and_org(dashboard_slug, self.current_org) + dashboard.is_archived = False + dashboard.record_changes(changed_by=self.current_user) + models.db.session.add(dashboard) + d = dashboard.to_dict(with_widgets=True, user=self.current_user) + models.db.session.commit() + return d + class PublicDashboardResource(BaseResource): def get(self, token): From 9456d3a43db745ff342c2adbcf1da96077cf210e Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Sun, 24 Dec 2017 11:48:12 +0900 Subject: [PATCH 2/6] Display an error message on failure to unarchive a dashboard --- client/app/pages/dashboards/dashboard.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/app/pages/dashboards/dashboard.js b/client/app/pages/dashboards/dashboard.js index 8c8dd25939..60974e63ab 100644 --- a/client/app/pages/dashboards/dashboard.js +++ b/client/app/pages/dashboards/dashboard.js @@ -202,6 +202,8 @@ function DashboardCtrl( Events.record('unarchive', 'dashboard', this.dashboard.id); $http.patch(url).success(() => { this.loadDashboard(); + }).error(() => { + toastr.error('Dashboard could not be unarchived.'); }); }; From 7c9d34490da3eb9c248ca079c6f945d590101f0f Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Wed, 27 Dec 2017 23:17:02 +0900 Subject: [PATCH 3/6] Move "Unarchive button" into button group --- client/app/pages/dashboards/dashboard.html | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/client/app/pages/dashboards/dashboard.html b/client/app/pages/dashboards/dashboard.html index d51058cdff..5fe8c3de3f 100644 --- a/client/app/pages/dashboards/dashboard.html +++ b/client/app/pages/dashboards/dashboard.html @@ -4,9 +4,7 @@

{{$ctrl.dashboard.name}} Unpublished -

@@ -53,7 +51,7 @@

{{$ctrl.dashboard.name}} -
+ From 340b7ce60d053c9296ec73ee0cc1290ef76248f4 Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Fri, 29 Dec 2017 16:33:22 +0900 Subject: [PATCH 4/6] Unarchive a dashboard without confirmation --- client/app/pages/dashboards/dashboard.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/client/app/pages/dashboards/dashboard.js b/client/app/pages/dashboards/dashboard.js index 60974e63ab..ae6dd3f79f 100644 --- a/client/app/pages/dashboards/dashboard.js +++ b/client/app/pages/dashboards/dashboard.js @@ -198,20 +198,12 @@ function DashboardCtrl( this.unArchiveDashboard = () => { const url = `api/dashboards/${this.dashboard.slug}/unarchive`; - const unarchive = () => { - Events.record('unarchive', 'dashboard', this.dashboard.id); - $http.patch(url).success(() => { - this.loadDashboard(); - }).error(() => { - toastr.error('Dashboard could not be unarchived.'); - }); - }; - - const title = 'Unarchive Dashboard'; - const message = `Are you sure you want to unarchive the "${this.dashboard.name}" dashboard?`; - const confirm = { class: 'btn-warning', title: 'Unarchive' }; - - AlertDialog.open(title, message, confirm).then(unarchive); + Events.record('unarchive', 'dashboard', this.dashboard.id); + $http.patch(url).success(() => { + this.loadDashboard(); + }).error(() => { + toastr.error('Dashboard could not be unarchived.'); + }); }; this.showManagePermissionsModal = () => { From 543efd4c4e305cd01892097a7ec914fda86eb6f6 Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Fri, 29 Dec 2017 17:18:51 +0900 Subject: [PATCH 5/6] Replace un unarchive method --- client/app/pages/dashboards/dashboard.js | 20 +++++++++++++------- client/app/services/dashboard.js | 5 +++++ redash/handlers/dashboards.py | 20 ++------------------ 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/client/app/pages/dashboards/dashboard.js b/client/app/pages/dashboards/dashboard.js index ae6dd3f79f..0237fe6842 100644 --- a/client/app/pages/dashboards/dashboard.js +++ b/client/app/pages/dashboards/dashboard.js @@ -4,7 +4,7 @@ import shareDashboardTemplate from './share-dashboard.html'; import './dashboard.less'; function DashboardCtrl( - $rootScope, $routeParams, $location, $timeout, $q, $uibModal, $http, + $rootScope, $routeParams, $location, $timeout, $q, $uibModal, Title, AlertDialog, Dashboard, currentUser, clientConfig, Events, dashboardGridOptions, toastr, ) { @@ -197,13 +197,19 @@ function DashboardCtrl( }; this.unArchiveDashboard = () => { - const url = `api/dashboards/${this.dashboard.slug}/unarchive`; Events.record('unarchive', 'dashboard', this.dashboard.id); - $http.patch(url).success(() => { - this.loadDashboard(); - }).error(() => { - toastr.error('Dashboard could not be unarchived.'); - }); + Dashboard.unarchive( + { + slug: this.dashboard.id, + is_archived: false, + }, + () => { + this.loadDashboard(); + }, + () => { + toastr.error('Dashboard could not be unarchived.'); + }, + ); }; this.showManagePermissionsModal = () => { diff --git a/client/app/services/dashboard.js b/client/app/services/dashboard.js index 04e5f74ad7..8439227fe7 100644 --- a/client/app/services/dashboard.js +++ b/client/app/services/dashboard.js @@ -50,6 +50,11 @@ function Dashboard($resource, $http, currentUser, Widget, dashboardGridOptions) url: 'api/dashboards/recent', transformResponse: transform, }, + unarchive: { + method: 'POST', + transformResponse: transform, + url: 'api/dashboards/:slug/unarchive', + }, }); resource.prototype.canEdit = function canEdit() { diff --git a/redash/handlers/dashboards.py b/redash/handlers/dashboards.py index 33f09dfea0..8c2e06d919 100644 --- a/redash/handlers/dashboards.py +++ b/redash/handlers/dashboards.py @@ -129,7 +129,8 @@ def post(self, dashboard_slug): require_object_modify_permission(dashboard, self.current_user) updates = project(dashboard_properties, ('name', 'layout', 'version', - 'is_draft', 'dashboard_filters_enabled')) + 'is_draft', 'dashboard_filters_enabled', + 'is_archived')) # SQLAlchemy handles the case where a concurrent transaction beats us # to the update. But we still have to make sure that we're not starting @@ -166,23 +167,6 @@ def delete(self, dashboard_slug): models.db.session.commit() return d - @require_permission('edit_dashboard') - def patch(self, dashboard_slug): - """ - Unarchives a dashboard. - - :qparam string slug: Slug of dashboard to retrieve. - - Responds with the archived :ref:`dashboard `. - """ - dashboard = models.Dashboard.get_by_slug_and_org(dashboard_slug, self.current_org) - dashboard.is_archived = False - dashboard.record_changes(changed_by=self.current_user) - models.db.session.add(dashboard) - d = dashboard.to_dict(with_widgets=True, user=self.current_user) - models.db.session.commit() - return d - class PublicDashboardResource(BaseResource): def get(self, token): From f9d71550ac229703d9c6a977e1bbafab63266d7e Mon Sep 17 00:00:00 2001 From: Katsuhiko YOSHIDA Date: Fri, 29 Dec 2017 17:21:18 +0900 Subject: [PATCH 6/6] Display an unarchived message --- client/app/pages/dashboards/dashboard.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/app/pages/dashboards/dashboard.js b/client/app/pages/dashboards/dashboard.js index 0237fe6842..45952d8bc6 100644 --- a/client/app/pages/dashboards/dashboard.js +++ b/client/app/pages/dashboards/dashboard.js @@ -205,6 +205,7 @@ function DashboardCtrl( }, () => { this.loadDashboard(); + toastr.success('Dashboard unarchived'); }, () => { toastr.error('Dashboard could not be unarchived.');