Skip to content

Commit

Permalink
Merge pull request #1381 from liveblog/hg/LBSD-2786-instance-settigs-ui
Browse files Browse the repository at this point in the history
[LBSD-2786] - Complete Instance Settings UI
  • Loading branch information
eos87 committed May 6, 2024
2 parents 78c4e66 + c6b52f0 commit a2db33d
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 155 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import {
EMBED_HEIGHT_RESPONSIVE_DEFAULT,
} from './../../liveblog-common/constants';

LiveblogSettingsController.$inject = ['$scope', 'api', '$location', 'notify', 'gettext', '$q'];
export default function LiveblogSettingsController($scope, api, $location, notify, gettext, $q) {
// prep the settings
const LiveblogSettingsController = ($scope, api, $location, notify, gettext, $q) => {
$scope.settingsForm = null;
$scope.liveblogSettings = {
language: {},
Expand Down Expand Up @@ -52,24 +50,26 @@ export default function LiveblogSettingsController($scope, api, $location, notif
$scope.settingsLoading = false;
});

$scope.setFormRef = function(childScope) {
$scope.setFormRef = (childScope) => {
$scope.settingsForm = childScope.settingsForm;
};

$scope.onTagsChange = function(tags) {
$scope.onTagsChange = (tags) => {
$scope.liveblogSettings.global_tags.value = tags;
$scope.settingsForm.$setDirty();
$scope.$apply();
};

$scope.saveSettings = function() {
$scope.saveSettings = () => {
notify.pop();
notify.info(gettext('Saving settings'));
let patch = {};
const reqArr = [];

_.forEach($scope.liveblogSettings, (item, key) => {
if (!_.includes(allowedKeys, key)) return;
if (!_.includes(allowedKeys, key)) {
return;
}

patch = {
key: key,
Expand All @@ -88,9 +88,12 @@ export default function LiveblogSettingsController($scope, api, $location, notif
});
};

$scope.close = function() {
$scope.close = () => {
// return to blog list page
$location.path('/liveblog/');
};
}
};

LiveblogSettingsController.$inject = ['$scope', 'api', '$location', 'notify', 'gettext', '$q'];

export default LiveblogSettingsController;
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
LiveblogInstanceSettingsController.$inject = ['$scope', 'api', '$location', 'notify', 'gettext'];
export default function LiveblogInstanceSettingsController($scope, api, $location, notify, gettext) {
const LiveblogInstanceSettingsController = (
$scope,
api,
$location,
notify,
gettext
) => {
$scope.instanceForm = null;
$scope.instanceSettings = {
settings: {},
settings: '{}', // has to be string in order to avoid json parsing error
};

$scope.settingsLoading = true;

api.instance_settings.query().then((data) => {
$scope.instanceSettings.settings = JSON.stringify(data._items[0].settings);
$scope.instanceSettings.settings = JSON.stringify(data._items[0]?.settings ?? '{}');

$scope.settingsLoading = false;
});

$scope.setFormRef = function(childScope) {
$scope.setFormRef = (childScope) => {
$scope.instanceForm = childScope.instanceForm;
};

$scope.saveInstanceSettings = function() {
$scope.saveInstanceSettings = () => {
let updatedSettings = $scope.instanceSettings.settings;

try {
Expand All @@ -31,22 +37,29 @@ export default function LiveblogInstanceSettingsController($scope, api, $locatio

api.instance_settings.save({ settings: updatedSettings })
.then(() => {
/* noop */
notify.pop();
notify.info(gettext('Instance settings saved successfully.'));
$scope.instanceForm.$setPristine();
})
.catch((error) => {
if (error.status === 422) {
notify.pop();
notify.info(gettext('Success. Existing instance settings config updated.'));
$scope.instanceForm.$setPristine();
} else {
notify.pop();
notify.error(gettext('Saving instance settings failed. Please try again later'));
}
.catch(({ data }) => {
const errMsg = data?._issues?.settings || data?._message;

notify.pop();
notify.error(errMsg, 10000);
});
};

$scope.close = function() {
$scope.close = () => {
$location.path('/liveblog/');
};
}
};

LiveblogInstanceSettingsController.$inject = [
'$scope',
'api',
'$location',
'notify',
'gettext',
];

export default LiveblogInstanceSettingsController;
15 changes: 13 additions & 2 deletions client/app/scripts/liveblog-settings/directives/lbSettingsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@
*/
import _ from 'lodash';

const lbSettingsView = ($route, superdesk, pageTitle) => {
const filterSupportTools = (settings, session, usersService) => {
if (!usersService.isSupport(session.identity)) {
return settings.filter((x) => x.liveblogSupportTools !== true);
}

return settings;
};

const lbSettingsView = ($route, superdesk, pageTitle, session, usersService) => {
return {
scope: {},
transclude: true,
templateUrl: 'scripts/apps/settings/views/settings-view.html',
link: (scope) => {
superdesk.getMenu(superdesk.MENU_SETTINGS).then((menu) => {
scope.settings = menu.filter((x) => x.liveblogSetting === true);

// filter settings that should only be available to support team
scope.settings = filterSupportTools(scope.settings, session, usersService);
});

scope.currentRoute = $route.current;
Expand All @@ -28,6 +39,6 @@ const lbSettingsView = ($route, superdesk, pageTitle) => {
};
};

lbSettingsView.$inject = ['$route', 'superdesk', 'pageTitle'];
lbSettingsView.$inject = ['$route', 'superdesk', 'pageTitle', 'session', 'usersService'];

export { lbSettingsView };
3 changes: 2 additions & 1 deletion client/app/scripts/liveblog-settings/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ const liveblogSettings = angular.module('liveblog.settings', [])
controller: LiveblogInstanceSettingsController,
templateUrl: instanceTpl,
category: superdesk.MENU_SETTINGS,
privileges: {global_preferences: 1},
liveblogSetting: true,
privileges: {instance_settings: 1},
liveblogSupportTools: true,
});
}])
.config(['apiProvider', function(apiProvider) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ <h5>{{ user.username}}</h5>
name="user_role"
id="user_role"
required
ng-options="role._id as role.name for role in roles | filter: {name: '!Instance Admin'}">
ng-options="role._id as role.name for role in roles">
</select>
<div class="sd-line-input__message" ng-show="userForm.user_role.$error.required" translate>This field is required.</div>
</div>
Expand Down
10 changes: 5 additions & 5 deletions server/liveblog/auth/db.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from flask import request
from apps.auth.db import DbAuthService
from settings import SUBSCRIPTION_LEVEL, ACCESS_SUBSCRIPTIONS_MOBILE
from flask import current_app as app

from superdesk.errors import SuperdeskApiError
from superdesk import get_resource_service

from apps.auth.db import DbAuthService
from apps.auth.errors import CredentialsAuthError

AGENT_MOBILE_ANDROID = "okhttp/"
Expand All @@ -16,15 +18,13 @@ def authenticate(self, credentials):
return super().authenticate(credentials)

def _check_subscription_level(self):
subscription = SUBSCRIPTION_LEVEL

# get user agent information to detect if request comes from mobile app
user_agent = request.user_agent.string
is_mobile_agent = any(
[(AGENT_MODILE_IOS in user_agent), (AGENT_MOBILE_ANDROID in user_agent)]
)

if subscription not in ACCESS_SUBSCRIPTIONS_MOBILE and is_mobile_agent:
if not app.features.is_enabled("mobile-app") and is_mobile_agent:
raise SuperdeskApiError.forbiddenError(
message="Liveblog mobile can not access on this subscription"
)
Expand Down
17 changes: 7 additions & 10 deletions server/liveblog/blogs/blogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@

from liveblog.common import get_user, update_dates_for
from settings import (
SUBSCRIPTION_LEVEL,
SUBSCRIPTION_MAX_ACTIVE_BLOGS,
DAYS_REMOVE_DELETED_BLOGS,
TRIGGER_HOOK_URLS,
)
Expand Down Expand Up @@ -294,14 +292,13 @@ def _blog_url(self, blog_id):
return "{}/#/liveblog/edit/{}".format(app.config["CLIENT_URL"], blog_id)

def _check_max_active(self, increment):
subscription = SUBSCRIPTION_LEVEL
if subscription in SUBSCRIPTION_MAX_ACTIVE_BLOGS:
active = self.find({"blog_status": "open"})
logger.info("active.count() %s " % active.count())
if active.count() + increment > SUBSCRIPTION_MAX_ACTIVE_BLOGS[subscription]:
raise SuperdeskApiError.forbiddenError(
message="Cannot add another active blog."
)
active = self.find({"blog_status": "open"})
current_blogs = active.count() + increment

if app.features.is_limit_reached("blogs", current_blogs):
raise SuperdeskApiError.forbiddenError(
message="Cannot add another active blog."
)

def make_embed_unavailable_if_needed(self, blog):
"""
Expand Down
31 changes: 23 additions & 8 deletions server/liveblog/blogs/tests/blogs_test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import liveblog.blogs as blog_app
import liveblog.advertisements as advert_app
import liveblog.client_modules as client_modules

from unittest.mock import MagicMock
from superdesk.tests import TestCase
from superdesk import get_resource_service
from superdesk.errors import SuperdeskApiError
from settings import SUBSCRIPTION_LEVEL, SUBSCRIPTION_MAX_ACTIVE_BLOGS
from liveblog.instance_settings.features_service import FeaturesService


def db_service_mock():
"""Mock database service with a method to simulate database config retrieval."""
db_service = MagicMock()
db_service.get_existing_config = MagicMock()
return db_service


class BlogsTestCase(TestCase):
def setUp(self):
self.app.features = FeaturesService(self.app, db_service_mock())

blog_app.init_app(self.app)
advert_app.init_app(self.app)
client_modules.init_app(self.app)

self.blog_with_output = {
"title": "Test blog",
Expand Down Expand Up @@ -62,21 +75,22 @@ def setUp(self):
}

def test_if_not_check_max_active(self):
self.app.features.current_sub_level = MagicMock(return_value="network")
increment = 0
self.assertEqual(
get_resource_service("blogs")._check_max_active(increment), None
)

def test_if_check_max_active(self):
if SUBSCRIPTION_LEVEL in SUBSCRIPTION_MAX_ACTIVE_BLOGS:
try:
increment = SUBSCRIPTION_MAX_ACTIVE_BLOGS[SUBSCRIPTION_LEVEL] + 5
except KeyError:
increment = 10
with self.assertRaises(SuperdeskApiError):
get_resource_service("blogs")._check_max_active(increment)
plan = "basic"
self.app.features._settings = {plan: {"limits": {"blogs": 5}}}
self.app.features.current_sub_level = MagicMock(return_value=plan)

with self.assertRaises(SuperdeskApiError):
get_resource_service("blogs")._check_max_active(10)

def test_auto_create_output(self):
self.app.features.current_sub_level = MagicMock(return_value="network")
get_resource_service("blogs")._auto_create_output(self.blog_with_output)
self.assertIsNotNone(
get_resource_service("outputs").find(
Expand All @@ -85,6 +99,7 @@ def test_auto_create_output(self):
)

def test_not_auto_create_output(self):
self.app.features.current_sub_level = MagicMock(return_value="network")
get_resource_service("blogs")._auto_create_output(self.blog_without_output)
with self.assertRaises(IndexError):
get_resource_service("outputs").find(
Expand Down

0 comments on commit a2db33d

Please sign in to comment.