Provider qa feedback (#1118)

* Ensure business plan is selected for providers

* Show add organization button on if user has valid orgs to add

* Correct client owner description

* No drop down options if you can't manage organizations
This commit is contained in:
Matt Gibson 2021-08-09 13:24:12 -04:00 committed by GitHub
parent 2b0d3f9e0d
commit 9bdda9cc4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 13 deletions

View File

@ -21,8 +21,6 @@ import { Provider } from 'jslib-common/models/domain/provider';
import { PlanType } from 'jslib-common/enums/planType'; import { PlanType } from 'jslib-common/enums/planType';
const DisallowedPlanTypes = [PlanType.Free, PlanType.FamiliesAnnually2019, PlanType.FamiliesAnnually];
@Component({ @Component({
selector: 'provider-add-organization', selector: 'provider-add-organization',
templateUrl: 'add-organization.component.html', templateUrl: 'add-organization.component.html',
@ -30,12 +28,12 @@ const DisallowedPlanTypes = [PlanType.Free, PlanType.FamiliesAnnually2019, PlanT
export class AddOrganizationComponent implements OnInit { export class AddOrganizationComponent implements OnInit {
@Input() providerId: string; @Input() providerId: string;
@Input() organizations: Organization[];
@Output() onAddedOrganization = new EventEmitter(); @Output() onAddedOrganization = new EventEmitter();
provider: Provider; provider: Provider;
formPromise: Promise<any>; formPromise: Promise<any>;
loading = true; loading = true;
organizations: Organization[];
constructor(private userService: UserService, private providerService: ProviderService, constructor(private userService: UserService, private providerService: ProviderService,
private toasterService: ToasterService, private i18nService: I18nService, private toasterService: ToasterService, private i18nService: I18nService,
@ -53,12 +51,6 @@ export class AddOrganizationComponent implements OnInit {
this.provider = await this.userService.getProvider(this.providerId); this.provider = await this.userService.getProvider(this.providerId);
const candidateOrgs = (await this.userService.getAllOrganizations()).filter(o => o.providerId == null);
const allowedOrgsIds = await Promise.all(candidateOrgs.map(o => this.apiService.getOrganization(o.id))).then(orgs =>
orgs.filter(o => !DisallowedPlanTypes.includes(o.planType))
.map(o => o.id));
this.organizations = candidateOrgs.filter(o => allowedOrgsIds.includes(o.id));
this.loading = false; this.loading = false;
} }

View File

@ -38,7 +38,7 @@
<td> <td>
<a [routerLink]="['/organizations', o.organizationId]">{{o.organizationName}}</a> <a [routerLink]="['/organizations', o.organizationId]">{{o.organizationName}}</a>
</td> </td>
<td class="table-list-options"> <td class="table-list-options" *ngIf="manageOrganizations">
<div class="dropdown" appListDropdown> <div class="dropdown" appListDropdown>
<button class="btn btn-outline-secondary dropdown-toggle" type="button" <button class="btn btn-outline-secondary dropdown-toggle" type="button"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"

View File

@ -15,6 +15,7 @@ import { PlatformUtilsService } from 'jslib-common/abstractions/platformUtils.se
import { SearchService } from 'jslib-common/abstractions/search.service'; import { SearchService } from 'jslib-common/abstractions/search.service';
import { UserService } from 'jslib-common/abstractions/user.service'; import { UserService } from 'jslib-common/abstractions/user.service';
import { PlanType } from 'jslib-common/enums/planType';
import { ProviderUserType } from 'jslib-common/enums/providerUserType'; import { ProviderUserType } from 'jslib-common/enums/providerUserType';
import { ValidationService } from 'jslib-angular/services/validation.service'; import { ValidationService } from 'jslib-angular/services/validation.service';
@ -22,6 +23,7 @@ import { ValidationService } from 'jslib-angular/services/validation.service';
import { import {
ProviderOrganizationOrganizationDetailsResponse ProviderOrganizationOrganizationDetailsResponse
} from 'jslib-common/models/response/provider/providerOrganizationResponse'; } from 'jslib-common/models/response/provider/providerOrganizationResponse';
import { Organization } from 'jslib-common/models/domain/organization';
import { ModalComponent } from 'src/app/modal.component'; import { ModalComponent } from 'src/app/modal.component';
@ -29,6 +31,8 @@ import { ProviderService } from '../services/provider.service';
import { AddOrganizationComponent } from './add-organization.component'; import { AddOrganizationComponent } from './add-organization.component';
const DisallowedPlanTypes = [PlanType.Free, PlanType.FamiliesAnnually2019, PlanType.FamiliesAnnually];
@Component({ @Component({
templateUrl: 'clients.component.html', templateUrl: 'clients.component.html',
}) })
@ -38,6 +42,7 @@ export class ClientsComponent implements OnInit {
providerId: any; providerId: any;
searchText: string; searchText: string;
addableOrganizations: Organization[];
loading = true; loading = true;
manageOrganizations = false; manageOrganizations = false;
showAddExisting = false; showAddExisting = false;
@ -77,7 +82,13 @@ export class ClientsComponent implements OnInit {
const response = await this.apiService.getProviderClients(this.providerId); const response = await this.apiService.getProviderClients(this.providerId);
this.clients = response.data != null && response.data.length > 0 ? response.data : []; this.clients = response.data != null && response.data.length > 0 ? response.data : [];
this.manageOrganizations = (await this.userService.getProvider(this.providerId)).type === ProviderUserType.ProviderAdmin; this.manageOrganizations = (await this.userService.getProvider(this.providerId)).type === ProviderUserType.ProviderAdmin;
this.showAddExisting = (await this.userService.getAllOrganizations()).some(org => org.providerId == null); const candidateOrgs = (await this.userService.getAllOrganizations()).filter(o => o.providerId == null);
const allowedOrgsIds = await Promise.all(candidateOrgs.map(o => this.apiService.getOrganization(o.id))).then(orgs =>
orgs.filter(o => !DisallowedPlanTypes.includes(o.planType))
.map(o => o.id));
this.addableOrganizations = candidateOrgs.filter(o => allowedOrgsIds.includes(o.id));
this.showAddExisting = this.addableOrganizations.length != 0;
this.loading = false; this.loading = false;
} }
@ -121,6 +132,7 @@ export class ClientsComponent implements OnInit {
const childComponent = this.modal.show<AddOrganizationComponent>(AddOrganizationComponent, this.addModalRef); const childComponent = this.modal.show<AddOrganizationComponent>(AddOrganizationComponent, this.addModalRef);
childComponent.providerId = this.providerId; childComponent.providerId = this.providerId;
childComponent.organizations = this.addableOrganizations;
childComponent.onAddedOrganization.subscribe(async () => { childComponent.onAddedOrganization.subscribe(async () => {
try { try {
await this.load(); await this.load();

View File

@ -33,7 +33,7 @@
<div class="form-group col-6" *ngIf="!!providerId"> <div class="form-group col-6" *ngIf="!!providerId">
<label for="email">{{'clientOwnerEmail' | i18n}}</label> <label for="email">{{'clientOwnerEmail' | i18n}}</label>
<input id="email" class="form-control" type="text" name="Email" [(ngModel)]="clientOwnerEmail" required> <input id="email" class="form-control" type="text" name="Email" [(ngModel)]="clientOwnerEmail" required>
<small class="text-muted">{{'ownerDesc' | i18n : '20'}}</small> <small class="text-muted">{{'clientOwnerDesc' | i18n : '20'}}</small>
</div> </div>
</div> </div>
<div *ngIf="!providerId"> <div *ngIf="!providerId">

View File

@ -90,6 +90,7 @@ export class OrganizationPlansComponent implements OnInit {
if (this.providerId) { if (this.providerId) {
this.ownedBusiness = true; this.ownedBusiness = true;
this.changedOwnedBusiness();
} }
this.loading = false; this.loading = false;

View File

@ -2251,7 +2251,7 @@
"message": "The highest access user that can manage all aspects of your organization." "message": "The highest access user that can manage all aspects of your organization."
}, },
"clientOwnerDesc": { "clientOwnerDesc": {
"message": "This email should NOT be associated with the provider. This user will have permissions to access and manage all aspects of this organization." "message": "This user should be independent of the Provider. If the Provider is disassociated with the organization, this user will maintain ownership of the organization."
}, },
"admin": { "admin": {
"message": "Admin" "message": "Admin"