LP1901930 SIP mediator continued
authorBill Erickson <berickxx@gmail.com>
Tue, 24 Nov 2020 23:13:18 +0000 (23:13 +0000)
committerBill Erickson <berickxx@gmail.com>
Mon, 30 Nov 2020 16:38:26 +0000 (08:38 -0800)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/admin/server/admin-server-splash.component.html
Open-ILS/src/eg2/src/app/staff/admin/server/sip/account.component.html
Open-ILS/src/eg2/src/app/staff/admin/server/sip/account.component.ts
Open-ILS/src/eg2/src/app/staff/admin/server/sip/account.module.ts
Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.ts [new file with mode: 0644]
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2.pm
Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Admin.pm [new file with mode: 0644]
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.sip-config.sql

index de399d6..42fb9e3 100644 (file)
@@ -90,6 +90,8 @@
       routerLink="/staff/admin/server/config/remote_account"></eg-link-table-link>
     <eg-link-table-link i18n-label label="Remote Authentication Profiles"  
       routerLink="/staff/admin/server/config/remoteauth_profile"></eg-link-table-link>
+    <eg-link-table-link i18n-label label="SIP Accounts"  
+      routerLink="/staff/admin/server/sip/account"></eg-link-table-link>
     <eg-link-table-link i18n-label label="SMS Carriers"  
       routerLink="/staff/admin/server/config/sms_carrier"></eg-link-table-link>
     <eg-link-table-link i18n-label label="User Activity Types"  
index 27aea9c..7fcfcc9 100644 (file)
@@ -7,12 +7,10 @@
   </button>
 </a>
 
-<eg-confirm-dialog #confirmDelete
-  i18n-dialogTitle i18n-dialogBody
-  dialogTitle="Confirm Delete"
-  dialogBody="Delete Setting Group 
-    {{account.setting_group() ? account.setting_group().label() : ''}}?">
-</eg-confirm-dialog>
+<eg-sip-group-delete-dialog *ngIf="account && account.setting_group()"
+  #deleteGroupDialog
+  [group]="account.setting_group()" [settingGroups]="settingGroups">
+</eg-sip-group-delete-dialog>
 
 <eg-fm-record-editor #cloneDialog idlClass="sipsetg" mode="create" 
   hiddenFields="id" fieldOrder="label,institution">
@@ -23,6 +21,7 @@
   [fieldOptions]="{name:{isReadonly:true}}">
 </eg-fm-record-editor>
 
+
 <div class="row mt-2" *ngIf="account">
   <div class="col-lg-7">
 
@@ -41,8 +40,8 @@
         <button class="btn btn-outline-info ml-2" 
           [disabled]="!account.setting_group()" (click)="openCloneDialog()" 
           i18n>Clone</button>
-        <button class="btn btn-outline-danger ml-2" 
-          [disabled]="!account.setting_group()" (click)="openDeleteDialog()
+        <button class="btn btn-outline-danger ml-2" (click)="openDeleteDialog()" 
+          [disabled]="!account.setting_group() || account.setting_group().id() == 1
           i18n>Delete</button>
       </div>
     </ng-template>
@@ -62,6 +61,7 @@
     <ul>
       <li i18n>Save account changes before modifying settings.</li>
       <li i18n>Setting values must be entered as valid JSON.</li>
+      <li i18n>The "Default Settings" settings group cannot be modified</li>
     </ul>
   </div>
 </div>
index 1502667..b37e38a 100644 (file)
@@ -9,7 +9,7 @@ import {PcrudService} from '@eg/core/pcrud.service';
 import {ToastService} from '@eg/share/toast/toast.service';
 import {StringComponent} from '@eg/share/string/string.component';
 import {StringService} from '@eg/share/string/string.service';
-import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
 import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
 import {ComboboxEntry, ComboboxComponent} from '@eg/share/combobox/combobox.component';
 import {GridComponent} from '@eg/share/grid/grid.component';
@@ -33,7 +33,7 @@ export class SipAccountComponent implements OnInit {
     @ViewChild('cloneDialog') cloneDialog: FmRecordEditorComponent;
     @ViewChild('settingDialog') settingDialog: FmRecordEditorComponent;
     @ViewChild('settingGrid') settingGrid: GridComponent;
-    @ViewChild('confirmDelete') confirmDelete: ConfirmDialogComponent;
+    @ViewChild('deleteGroupDialog') deleteGroupDialog: DialogComponent;
 
     constructor(
         private route: ActivatedRoute,
@@ -154,6 +154,14 @@ export class SipAccountComponent implements OnInit {
     }
 
     openDeleteDialog() {
+
+        this.deleteGroupDialog.open().subscribe(
+            ok => {
+                console.log('group deleted');
+            }
+        );
+
+
         /*
         const grp = this.account.setting_group();
 
@@ -200,6 +208,9 @@ export class SipAccountComponent implements OnInit {
     }
 
     editSetting(row: any) {
+        // Default Settings group is read-only
+        if (row.setting_group() === 1) { return; }
+
         this.settingDialog.record = this.idl.clone(row);
         this.settingDialog.open().subscribe(
             ok => {
index 5ab590f..d97d354 100644 (file)
@@ -3,11 +3,13 @@ import {AdminCommonModule} from '@eg/staff/admin/common.module';
 import {SipAccountRoutingModule} from './routing.module';
 import {SipAccountListComponent} from './account-list.component';
 import {SipAccountComponent} from './account.component';
+import {DeleteGroupDialogComponent} from './delete-group-dialog.component';
 
 @NgModule({
   declarations: [
     SipAccountComponent,
-    SipAccountListComponent
+    SipAccountListComponent,
+    DeleteGroupDialogComponent
   ],
   imports: [
     AdminCommonModule,
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.html
new file mode 100644 (file)
index 0000000..d1eb51b
--- /dev/null
@@ -0,0 +1,37 @@
+<ng-template #dialogContent>
+  <div class="modal-header bg-info">
+    <h4 class="modal-title" i18n>Delete Setting Group</h4>
+    <button type="button" class="close" 
+      i18n-aria-label aria-label="Close" (click)="close()">
+      <span aria-hidden="true">&times;</span>
+    </button>
+  </div>
+  <div class="modal-body">
+    <div class="row">
+      <div class="col-lg-12" *ngIf="group" i18n>
+        Deleting SIP setting group: {{group.label()}}
+      </div>
+    </div>
+    <div class="row mt-2 pt-2 border-top">
+      <div class="col-lg-12" i18n>
+        Select another group to act as the transfer target group.
+        Any SIP accounts linked to the deleted group will be transferred
+        to this group:
+      </div>
+    </div>
+    <div class="row mt-2 pt-2 border-top">
+      <div class="col-lg-8 offset-lg-2" i18n>
+        <eg-combobox #grpCbox required="true" [selectedId]="targetGroup"
+          [entries]="trimmedSettingGroups" (onChange)="grpChanged($event)">
+        </eg-combobox>
+      </div>
+    </div>
+
+  </div>
+  <div class="modal-footer">
+    <button type="button" class="btn btn-success" 
+      (click)="close(true)" i18n>Confirm</button>
+    <button type="button" class="btn btn-warning" 
+      (click)="close(false)" i18n>Cancel</button>
+  </div>
+</ng-template>
diff --git a/Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/admin/server/sip/delete-group-dialog.component.ts
new file mode 100644 (file)
index 0000000..1912a99
--- /dev/null
@@ -0,0 +1,53 @@
+import {Component, Input, ViewChild, OnInit} from '@angular/core';
+import {Observable, of} from 'rxjs';
+import {map, tap, switchMap, catchError} from 'rxjs/operators';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {PcrudService} from '@eg/core/pcrud.service';
+import {NetService} from '@eg/core/net.service';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {StringComponent} from '@eg/share/string/string.component';
+import {StringService} from '@eg/share/string/string.service';
+import {NgbModal, NgbModalRef, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {FmRecordEditorComponent} from '@eg/share/fm-editor/fm-editor.component';
+import {ComboboxEntry, ComboboxComponent} from '@eg/share/combobox/combobox.component';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {Pager} from '@eg/share/util/pager';
+
+@Component({
+    templateUrl: './delete-group-dialog.component.html',
+    selector: 'eg-sip-group-delete-dialog'
+})
+export class DeleteGroupDialogComponent extends DialogComponent implements OnInit {
+
+    @Input() group: IdlObject;
+    @Input() settingGroups: ComboboxEntry[];
+    targetGroup = 1;  // Default to the 'Default Settings' group.
+    trimmedSettingGroups: ComboboxEntry[];
+
+    constructor(
+        private modal: NgbModal,
+        private idl: IdlService,
+        private net: NetService
+    ) {
+        super(modal);
+    }
+
+    ngOnInit() {
+        this.onOpen$.subscribe(_ => {
+            console.log('my group', this.group);
+            this.trimmedSettingGroups = this.settingGroups.filter(
+                entry => entry.id !== this.group.id());
+        });
+    }
+
+    grpChanged(entry: ComboboxEntry) {
+        if (entry) {
+            this.targetGroup = entry.id;
+        }
+    }
+}
+
index 240ea7c..2fce9f2 100644 (file)
@@ -18,6 +18,7 @@ use OpenILS::Application::SIP2::Patron;
 use OpenILS::Application::SIP2::Checkout;
 use OpenILS::Application::SIP2::Checkin;
 use OpenILS::Application::SIP2::Payment;
+use OpenILS::Application::SIP2::Admin;
 
 my $U = 'OpenILS::Application::AppUtils';
 my $SC = 'OpenILS::Application::SIP2::Common';
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Admin.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/SIP2/Admin.pm
new file mode 100644 (file)
index 0000000..fc51337
--- /dev/null
@@ -0,0 +1,66 @@
+package OpenILS::Application::SIP2::Admin;
+use strict; use warnings;
+use base 'OpenILS::Application';
+use OpenILS::Event;
+use OpenILS::Application;
+use OpenILS::Utils::Fieldmapper;
+use OpenSRF::Utils::Logger qw(:logger);
+use OpenILS::Utils::CStoreEditor qw/:funcs/;
+use OpenILS::Application::AppUtils;
+
+my $U = 'OpenILS::Application::AppUtils';
+
+__PACKAGE__->register_method(
+    method    => 'delete_setting_group',
+    api_name  => 'open-ils.sip2.setting_group.delete',
+    api_level => 1,
+    argc      => 2,
+    signature => {
+        desc     => q/
+            Takes a SIP2 JSON message and handles the request/,
+        params   => [{   
+            name => 'auth',
+            desc => 'Authtoken',
+            type => 'string'
+        }, {
+            name => 'del_grp_id',
+            desc => 'Setting group ID to delete',
+            type => 'number',
+        }, {
+            name => 'xfer_grp_id',
+            desc => q/Setting group ID to use as account transfer destination.
+                    If no destination group is specified, defaults to setting
+                    group ID 1 (Defaults)/,
+            type => 'number',
+        }],
+        return => {
+            desc => q/1 on success, Event on error/,
+            type => 'number | object'
+        }
+    }
+);
+
+sub dispatch_sip2_request {
+    my ($self, $client, $auth, $del_grp_id, $xfer_grp_id) = @_;
+    $xfer_grp_id ||= 1; # Defaults Group
+    
+    my $e = new_editor(authtoken => $auth, xact => 1);
+    return $e->die_event unless $e->allowed('SIP_ADMIN');
+
+    return $e->die_event unless
+        my $grp = $e->retrieve_sip_setting_group($del_grp_id);
+
+    my $accounts = $e->search_sip_account({setting_group => $del_grp_id});
+
+    for my $acc (@$accounts) {
+        $acc->setting_group($xfer_grp_id);
+        return $e->die_event unless $e->update_sip_account($acc);
+    }
+
+    # note: sip.setting objects are deleted via cascade
+    return $e->die_event unless $e->delete_sip_setting_group($grp);
+
+    return 1;
+}
+
+1;
index ea6dde4..3835e8f 100644 (file)
@@ -159,8 +159,7 @@ INSERT INTO actor.workstation (name, owning_lib) VALUES ('BR1-SIP2-Gateway', 4);
 INSERT INTO sip.account(
     setting_group, sip_username, sip_password, usr, workstation
 ) VALUES (
-    (SELECT id FROM config.sip_setting_group WHERE institution = 'example'), 
-    'admin', 
+    1, 'admin', 
     (SELECT id FROM actor.passwd WHERE usr = 1 AND passwd_type = 'sip2'),
     1, 
     (SELECT id FROM actor.workstation WHERE name = 'BR1-SIP2-Gateway')