class BypassUserProfileDialog extends EICDialogContent { actions = [ { label: 'Cancel', onclick: this.cancel.bind(this), severity: 'secondary', role: 'cancel' }, { label: 'Add user', onclick: this.create.bind(this), severity: 'primary', role: 'add', disabled: true }, ] async DOMContentLoaded(options) { this.mode = options.mode ? options.mode: 'create'; this.model = options.model; this.profile = options.profile; let components = ui.eicfy(this.el); this.euid = components.find(component => component.el.dataset.path == 'euid'); this.firstname = components.find(component => component.el.dataset.path == 'firstname'); this.lastname = components.find(component => component.el.dataset.path == 'lastname'); this.email = components.find(component => component.el.dataset.path == 'email'); this.genderSelect = components.find(component => component.el.dataset.path == 'gender'); this.roleSelect = components.find(component => component.el.dataset.path == 'role'); this.roleSelect.block = this.find('.roleSelector') this.trackSelect = components.find(component => component.el.dataset.path == 'track'); this.trackSelect.block = this.find('.trackSelector') this.domainSelect = components.find(component => component.el.dataset.path == 'domain'); this.domainSelect.block = this.find('.domainSelector'); this.userSearcButton = components.find(component => component.el.classList.contains('user-search')); this.genderSelect.change(this.changeRoleAvailable.bind(this)); this.roleSelect.change(this.onRoleChange.bind(this)); this.roleSelect.disabled = true; this.trackSelect.change(this.onTrackChange.bind(this)); this.trackSelect.disabled = true; this.domainSelect.change(this.onDomainChange.bind(this)); this.domainSelect.disabled = true; this.form = new Form(this.find('.user-dialog')); let tracks = app.meta.toOptions(app.meta.getCollection('accelerator-tracks'), null, true); tracks.forEach(item => this.trackSelect.el.append(item)); this.roleDelegations = {} this.roleDelegations = await app.Assets.loadJson({name:'global/bypass/roleDelegations.json'}) this.userSearcButton.el.addEventListener('click', this.onUserSearch.bind(this)); } changeRoleAvailable() { if( this.form.validateField(this.euid).valid && this.form.validateField(this.firstname).valid && this.form.validateField(this.lastname).valid && this.form.validateField(this.email).valid && this.form.validateField(this.genderSelect).valid ) { this.roleSelect.disabled = false; this.changeAddAvailable(); let roles4select = this.getDelegationRules().map(x=>x.role); let options = app.meta.toOptions(roles4select.map(x=>({id:x, label:x})), '', true) this.roleSelect.empty(); options.forEach(item => this.roleSelect.el.append(item)); ui.show(this.roleSelect.block); } else { this.hideSelect(this.roleSelect); } } changeAddAvailable() { if(this.form.validate() && this.validateDelegation()) { this.actions.find(o => o.role == 'add').button.disabled = false; } else { this.actions.find(o => o.role == 'add').button.disabled = true; } } getDelegationRules() { /* In delegations, which of my roles shall I use as master... (no role hierarchy) For now priority is top-down in the roleDelegation masters order. Bad, not 100% reliable, but in our case, there should be no conflicts (mutually exclusive in delegations) */ let delegationsRules = []; for(let roleDeleg of this.roleDelegations){ if(app.User.hasRole(roleDeleg.master)) { delegationsRules = roleDeleg.surrogates; break; } } return(delegationsRules) } hideSelect(sel) { sel.disabled = true; sel.value = ''; ui.hide(sel.block); } ruleSelect(rule, sel, inheritValue) { if(rule=='inherit') { // Forced to my own value sel.disabled = true; sel.value = inheritValue; ui.show(sel.block); } else if(rule=='set') { // Can choose sel.disabled = false; ui.show(sel.block); } else if(rule=='ignore'){ // Not applicable this.hideSelect(sel); } else { // Forced to fixed value sel.disabled = true; sel.value = rule; ui.show(sel.block); } } validateDelegation(){ let rules = this.getDelegationRules().find(x => x.role==this.roleSelect.value); if(!rules) return(false) const validateSel = (rule, sel, inheritValue) => { let ok = false; if(rule=='inherit') ok = (sel.value == inheritValue) else if(rule=='set') ok = Boolean(sel.value) else if(rule=='ignore') ok = (true) else ok = (sel.value == rule) if(ok) sel.el.nextSibling.classList.remove('validation-failed'); else sel.el.nextSibling.classList.add('validation-failed'); return(ok) } return( validateSel(rules.track, this.trackSelect, this.profile.track) && validateSel(rules.domain, this.domainSelect, this.profile.domain) ) } onRoleChange(event) { if(event) { event.preventDefault(); event.stopPropagation(); } // pas de role: pas de track, pas de track : pas de domaine, pas de domaine: pas de palais, etc if(!this.roleSelect.value){ this.hideSelect(this.trackSelect); this.hideSelect(this.domainSelect); return } let rules = this.getDelegationRules().find(x => x.role==this.roleSelect.value); if(!rules) { console.warn('Delegation not found for role '+this.roleSelect.value); this.hideSelect(this.trackSelect); this.hideSelect(this.domainSelect); return } this.ruleSelect(rules.track, this.trackSelect, this.profile.track); this.onTrackChange(); this.ruleSelect(rules.domain, this.domainSelect, this.profile.domain); this.changeAddAvailable(); } onUserSearch(event) { this.userSearcButton.loading = true; this.model.search(this.euid.value).then( (userList => { this.userSearcButton.loading = false; if(userList.length==0) return // TODO better manage if several (take most complete?) let user = userList[0]; this.euid.value = user.uid; this.firstname.value = user.given_name; this.lastname.value = user.family_name; this.email.value = user.email; this.changeRoleAvailable(); }), (err) => { this.userSearcButton.loading = false; } ); } onTrackChange(event) { if(event){ event.preventDefault(); event.stopPropagation(); } if(this.trackSelect.value) { this.fillDomain(this.trackSelect.value); } else { this.domainSelect.empty(); this.hideSelect(this.domainSelect); } this.changeAddAvailable(); } onDomainChange(event) { event.preventDefault(); event.stopPropagation(); this.changeAddAvailable(); } fillDomain(track, domain) { let domains = track ? app.meta.toOptions(app.meta.getItem('accelerator-tracks', track).children, domain, true): []; this.domainSelect.empty(); domains.forEach(item => this.domainSelect.el.append(item)); } DOMContentFocused() { } create(event) { if(this.form.validate() && this.validateDelegation()) { this.actions.find(o => o.role == 'add').button.loading = true; this.actions.find(o => o.role == 'cancel').button.disabled = true; this.model.create(this.form.value) .then( this.onSuccess.bind(this), this.onFailed.bind(this)) } } onSuccess() { this.actions.find(o => o.role == 'add').button.loading = false; this.actions.find(o => o.role == 'cancel').button.disabled = false; this.commit(true); } onFailed() { this.actions.find(o => o.role == 'add').button.loading = false; this.actions.find(o => o.role == 'cancel').button.disabled = false; this.abort(); } } app.registerClass('BypassUserProfileDialog', BypassUserProfileDialog);