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"
</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">
[fieldOptions]="{name:{isReadonly:true}}">
</eg-fm-record-editor>
+
<div class="row mt-2" *ngIf="account">
<div class="col-lg-7">
<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>
<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>
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';
@ViewChild('cloneDialog') cloneDialog: FmRecordEditorComponent;
@ViewChild('settingDialog') settingDialog: FmRecordEditorComponent;
@ViewChild('settingGrid') settingGrid: GridComponent;
- @ViewChild('confirmDelete') confirmDelete: ConfirmDialogComponent;
+ @ViewChild('deleteGroupDialog') deleteGroupDialog: DialogComponent;
constructor(
private route: ActivatedRoute,
}
openDeleteDialog() {
+
+ this.deleteGroupDialog.open().subscribe(
+ ok => {
+ console.log('group deleted');
+ }
+ );
+
+
/*
const grp = this.account.setting_group();
}
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 => {
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,
--- /dev/null
+<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">×</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>
--- /dev/null
+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;
+ }
+ }
+}
+
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';
--- /dev/null
+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;
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')