Skip to content

Commit

Permalink
Merge pull request #1379 from liveblog/hg/LBSD-2785-implement-feature…
Browse files Browse the repository at this point in the history
…s-service

[LBSD-2785] - Implement features service to check for subscription limits
  • Loading branch information
eos87 committed Apr 30, 2024
2 parents a3b3f19 + 835ae2d commit 1c23320
Show file tree
Hide file tree
Showing 27 changed files with 2,879 additions and 2,296 deletions.
2 changes: 1 addition & 1 deletion client/app/scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import 'liveblog-analytics';
import 'liveblog-advertising';

import 'liveblog-security.service';
import 'liveblog-features.service';

// eslint-disable-next-line
const config = __SUPERDESK_CONFIG__;
Expand Down Expand Up @@ -125,7 +126,6 @@ const sdCore = angular.module('superdesk.core', [
'superdesk.core.loading',
'superdesk.core.editor3',
'superdesk.core.services',

'superdesk.core.directives',
]);

Expand Down
47 changes: 18 additions & 29 deletions client/app/scripts/liveblog-bloglist/controllers/blog-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import _ from 'lodash';
BlogListController.$inject = [
'$scope',
'$location',
'$http',
'api',
'gettext',
'upload',
Expand All @@ -16,12 +15,12 @@ BlogListController.$inject = [
'urls',
'modal',
'blogService',
'featuresService',
];

export default function BlogListController(
$scope,
$location,
$http,
api,
gettext,
upload,
Expand All @@ -32,7 +31,9 @@ export default function BlogListController(
config,
urls,
modal,
blogService) {
blogService,
featuresService
) {
$scope.maxResults = 25;
$scope.states = [
ACTIVE_STATE,
Expand Down Expand Up @@ -322,11 +323,10 @@ export default function BlogListController(
$scope.accessRequestedTo = blog;
$scope.showBlogAccessModal = true;

if (config.subscriptionLevel
&& ['solo', 'team'].indexOf(config.subscriptionLevel) !== -1) {
$scope.checkAccessRequestLimit(blog);
} else {
if (featuresService.isNetworkSubscription()) {
$scope.allowAccessRequest = true;
} else {
$scope.checkAccessRequestLimit(blog);
}
};

Expand All @@ -348,23 +348,18 @@ export default function BlogListController(
});
}

$http({
url: config.server.url + '/blogs/' + blog._id + '/request_membership',
method: 'GET',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
})
api
.get(`/blogs/${blog._id}/request_membership`)
.then((response) => {
if (response.data._items.length > 0) {
response.data._items.forEach((item) => {
if (theoricalMembers.indexOf(item._id) === -1) {
theoricalMembers.push(item._id);
}
});
}
(response._items || []).forEach((item) => {
if (theoricalMembers.indexOf(item._id) === -1) {
theoricalMembers.push(item._id);
}
});

const isMembersLimitReached = featuresService.isLimitReached('blog_members', theoricalMembers.length);

if (theoricalMembers.length < config.assignableUsers[config.subscriptionLevel]) {
if (!isMembersLimitReached) {
$scope.allowAccessRequest = true;
}
});
Expand Down Expand Up @@ -442,13 +437,7 @@ export default function BlogListController(
});
};

$scope.hasReachedMembersLimit = function() {
if (!_.has(config.assignableUsers, config.subscriptionLevel)) {
return false;
}

return $scope.blogMembers.length >= config.assignableUsers[config.subscriptionLevel];
};
$scope.hasReachedMembersLimit = () => featuresService.isLimitReached('blog_members', $scope.blogMembers.length);

// Set grid or list view
$scope.setBlogsView = function(blogsView) {
Expand Down
14 changes: 5 additions & 9 deletions client/app/scripts/liveblog-edit/controllers/blog-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ BlogSettingsController.$inject = [
'$rootScope',
'$routeParams',
'postsService',
'featuresService',
];

function BlogSettingsController(
Expand All @@ -56,7 +57,8 @@ function BlogSettingsController(
superdesk,
$rootScope,
$routeParams,
postsService
postsService,
featuresService
) {
// set view's model
/* eslint consistent-this: ["error", "vm"]*/
Expand Down Expand Up @@ -126,7 +128,7 @@ function BlogSettingsController(
config.subscriptionLevel,
blog: blog,
newBlog: angular.copy(blog),
deactivateTheme: config.subscriptionLevel === 'solo',
isThemeSelectorEnabled: featuresService.isEnabled('change_blog_theme'),
blogPreferences: angular.copy(blog.blog_preferences),
consumersSettings: angular.copy(blog.consumers_settings),
availableLanguages: [],
Expand Down Expand Up @@ -336,13 +338,7 @@ function BlogSettingsController(
vm.memberRequests.splice(vm.memberRequests.indexOf(user), 1);
vm.acceptedMembers.push(user);
},
hasReachedMembersLimit: function() {
if (!_.has(config.assignableUsers, config.subscriptionLevel)) {
return false;
}

return vm.blogMembers.length >= config.assignableUsers[config.subscriptionLevel];
},
hasReachedMembersLimit: () => featuresService.isLimitReached('blog_members', vm.blogMembers.length),
removeMember: function(user) {
vm.blogMembers.splice(vm.blogMembers.indexOf(user), 1);
},
Expand Down
19 changes: 17 additions & 2 deletions client/app/scripts/liveblog-edit/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const app = angular.module('liveblog.edit',
'liveblog.pages-manager',
'lrInfiniteScroll',
'liveblog.security',
'liveblog.features',
'liveblog.freetypes',
'liveblog.edit.components.inactivityModal',
])
Expand Down Expand Up @@ -265,12 +266,26 @@ const app = angular.module('liveblog.edit',
embedServiceProvider.setConfig('fallbackService', 'iframely');
},
])
.run(['embedService', 'embedInstagramHandler', 'embedFacebookHandler', 'embedPictureHandler', 'embedTwitterHandler',
function(embedService, embedInstagramHandler, embedFacebookHandler, embedPictureHandler, embedTwitterHandler) {
.run([
'embedService',
'embedInstagramHandler',
'embedFacebookHandler',
'embedPictureHandler',
'embedTwitterHandler',
'featuresService',
function(
embedService,
embedInstagramHandler,
embedFacebookHandler,
embedPictureHandler,
embedTwitterHandler,
featuresService
) {
embedService.registerHandler(embedInstagramHandler);
embedService.registerHandler(embedFacebookHandler);
embedService.registerHandler(embedPictureHandler);
embedService.registerHandler(embedTwitterHandler);
featuresService.initialize();
},
]);

Expand Down
2 changes: 1 addition & 1 deletion client/app/scripts/liveblog-edit/views/settings.ng1
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
<label for="inputTheme" class="control-label" translate>Theme</label>
<div class="form-input">
<select
ng-disabled="settings.deactivateTheme"
ng-disabled="!settings.isThemeSelectorEnabled"
ng-model="settings.selectedTheme"
ng-change="settings.blogPreferences.theme = settings.selectedTheme.name"
ng-options="theme as theme.label for theme in settings.availableThemes track by theme.name"
Expand Down
70 changes: 70 additions & 0 deletions client/app/scripts/liveblog-features.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
interface ISettings {
features: { [key: string]: boolean };
limits: { [key: string]: number };
isNetworkSubscription: boolean;
}

class FeaturesService {
api: any;
private settings: ISettings = null;

constructor(api) {
this.api = api;
}

async initialize(): Promise<void> {
try {
await this.loadSettings();
} catch (error) {
console.warn('There has been an error fetching instance settings');
}
}

/**
* Gets the settings from cache or loads them if not already loaded.
* @returns A promise that resolves to the settings object.
*/
private async loadSettings(): Promise<void> {
this.settings = await this.api.get('/instance_settings/current');
}

isNetworkSubscription = () => this.settings.isNetworkSubscription;

/**
* Determines if a specific feature is enabled based on the current settings.
* If the "network" subscription is active, all features are considered enabled.
*/
isEnabled = (featureName: string) => {
const settings = this.settings;

if (settings.isNetworkSubscription) {
return true;
}

return settings?.features[featureName] ?? false;
}

/**
* Determines if the limit for a specific feature has been reached.
* If the "network" subscription plan is active, there are no limits.
*/
isLimitReached = (featureName: string, currentUsage: number) => {
const settings = this.settings;

if (settings.isNetworkSubscription) {
return false;
}

const subscriptionLimit = settings?.limits[featureName] ?? 0;

return currentUsage >= subscriptionLimit;
}
}

angular.module('liveblog.features', [])
.service('featuresService', ['api', (api) => {
const featuresService = new FeaturesService(api);

featuresService.initialize();
return featuresService;
}]);
39 changes: 23 additions & 16 deletions client/app/scripts/liveblog-freetypes/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ LiveblogFreetypesController.$inject = [
'$q',
'modal',
'privileges',
'featuresService',
'config',
];

function LiveblogFreetypesController(
Expand All @@ -15,7 +17,9 @@ function LiveblogFreetypesController(
gettext,
$q,
modal,
privileges
privileges,
featuresService,
config
) {
const self = this;

Expand Down Expand Up @@ -62,6 +66,11 @@ function LiveblogFreetypesController(
name: '',
template: '',
},
isFreetypesManagerEnabled: () => featuresService.isEnabled('freetypes_manager'),
mailto: 'mail:upgrade@liveblog.pro?subject=' +
encodeURIComponent(location.hostname) +
' ' +
config.subscriptionLevel,
// open dialog for adding editing an item type
openFreetypeDialog: function(freetype) {
self.checkItemIsUsed(freetype).then(() => {
Expand Down Expand Up @@ -188,21 +197,19 @@ function LiveblogFreetypesController(
getFreetypes();
}

const liveblogFreetypesModule = angular.module('liveblog.freetypes', [])
.config(['superdeskProvider', 'config', function(superdesk, config) {
if (config.subscriptionLevel !== 'solo') {
superdesk
.activity('/freetypes/', {
label: gettext('Free types manager'),
controller: LiveblogFreetypesController,
controllerAs: 'self',
betaMark: false,
category: superdesk.MENU_MAIN,
adminTools: true,
privileges: {global_preferences: 1},
templateUrl: listViewTpl,
});
}
const liveblogFreetypesModule = angular.module('liveblog.freetypes', ['liveblog.features'])
.config(['superdeskProvider', function(superdesk) {
superdesk
.activity('/freetypes/', {
label: gettext('Free types manager'),
controller: LiveblogFreetypesController,
controllerAs: 'self',
betaMark: false,
category: superdesk.MENU_MAIN,
adminTools: true,
privileges: {global_preferences: 1},
templateUrl: listViewTpl,
});
}])
.config(['apiProvider', function(apiProvider) {
apiProvider.api('freetypes', {
Expand Down

0 comments on commit 1c23320

Please sign in to comment.