11import * as ko from "knockout" ;
2- import { BuiltInRoles , UserService } from "@paperbits/common/user" ;
2+ import { UserService } from "@paperbits/common/user" ;
33import { EventManager } from "@paperbits/common/events" ;
44import { RoleBasedSecurityModel } from "@paperbits/common/security/roleBasedSecurityModel" ;
5+ import { RoleBasedSecuredBehavior , RoleBasedSecuredBehaviorConfig } from "@paperbits/common/behaviors/behavior.roleBasedSecured" ;
56
67
78export class RoleBasedSecuredBindingHandler {
@@ -10,48 +11,45 @@ export class RoleBasedSecuredBindingHandler {
1011 private readonly userService : UserService
1112 ) {
1213 ko . bindingHandlers [ "secured" ] = {
13- init : ( element : HTMLElement , valueAccessor : any ) => {
14- const securityModel = ko . unwrap ( valueAccessor ( ) ) ;
15- const initiallyAssignedRoles = securityModel ?. roles ;
16- const dataRoleObservable : ko . Observable < string > = ko . observable ( initiallyAssignedRoles ) ;
17- const hiddenObservable : ko . Observable < boolean > = ko . observable ( false ) ;
18-
19- const applyRoles = ( securityModel : RoleBasedSecurityModel ) => { // has to be synchronous to be applied during publishing
20- const widgetRoles = securityModel ?. roles || [ BuiltInRoles . everyone . key ] ;
21-
22- const roles = widgetRoles
23- && widgetRoles . length === 1
24- && widgetRoles [ 0 ] === BuiltInRoles . everyone . key
25- ? null
26- : widgetRoles . join ( "," ) ;
27-
28- dataRoleObservable ( roles ) ;
29- applyVisibility ( ) ;
30- } ;
14+ init : ( element : HTMLElement , valueAccessor : ( ) => ko . Observable < RoleBasedSecurityModel > | RoleBasedSecurityModel ) => {
15+ const securityModelObservableOrStatic = valueAccessor ( ) ;
16+ const initialSecurityModel = ko . unwrap ( securityModelObservableOrStatic ) ;
3117
32- const applyVisibility = async ( ) => { // doesn't have to be synchronous, used in design- and run-time only
33- const widgetRolesString = dataRoleObservable ( ) ;
34- const widgetRoles = ! ! widgetRolesString ? widgetRolesString . split ( "," ) : [ BuiltInRoles . everyone . key ] ;
35- const userRoles = await this . userService . getUserRoles ( ) ;
36- const visibleToUser = userRoles . some ( x => widgetRoles . includes ( x ) ) || widgetRoles . includes ( BuiltInRoles . everyone . key ) ;
18+ const dataRoleObservable : ko . Observable < string | null > = ko . observable ( null ) ;
19+ const hiddenObservable : ko . Observable < boolean > = ko . observable ( false ) ;
3720
38- hiddenObservable ( ! visibleToUser ) ;
21+ const behaviorConfig : RoleBasedSecuredBehaviorConfig = {
22+ initialSecurityModel : initialSecurityModel ,
23+ userService : this . userService ,
24+ eventManager : this . eventManager ,
25+ onUpdate : ( roles , isHidden ) => {
26+ dataRoleObservable ( roles ) ;
27+ hiddenObservable ( isHidden ) ;
28+ }
3929 } ;
4030
41- this . eventManager . addEventListener ( "onUserRoleChange" , applyVisibility ) ;
31+ const behaviorHandle = RoleBasedSecuredBehavior . attach ( element , behaviorConfig ) ;
4232
4333 ko . applyBindingsToNode ( element , {
4434 attr : { "data-role" : dataRoleObservable } ,
4535 css : { hidden : hiddenObservable }
4636 } , null ) ;
4737
38+ let subscription : ko . Subscription | undefined ;
39+ if ( ko . isObservable ( securityModelObservableOrStatic ) ) {
40+ subscription = securityModelObservableOrStatic . subscribe ( ( newModel ) => {
41+ behaviorHandle . update && behaviorHandle . update ( newModel ) ;
42+ } ) ;
43+ }
44+
4845 ko . utils . domNodeDisposal . addDisposeCallback ( element , ( ) => {
49- this . eventManager . removeEventListener ( "onUserRoleChange" , applyVisibility ) ;
46+ if ( subscription ) {
47+ subscription . dispose ( ) ;
48+ }
49+ if ( behaviorHandle && behaviorHandle . detach ) {
50+ behaviorHandle . detach ( ) ;
51+ }
5052 } ) ;
51-
52- const assignedRolesObsevable : ko . Observable < RoleBasedSecurityModel > = valueAccessor ( ) ;
53- assignedRolesObsevable . subscribe ( applyRoles ) ;
54- applyRoles ( securityModel ) ;
5553 }
5654 } ;
5755 }
0 commit comments