{"title":"Правое меню для Call-Center (test)","template":"\u003cstyle\u003e\n .right-sidebar {\n height:100vh;\n \n \n \n width: 300px;\n background-color: #121E2C;\n z-index: 998;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px; \n }\n \n\u003c/style\u003e\n\n\n\n\n\u003caudio id=\"audio\" width=\"100%\" autoplay playsinline\u003e\u003c/audio\u003e\n\u003caudio id=\"audio2\" width=\"100%\" autoplay playsinline\u003e\u003c/audio\u003e\n\n\u003c!--\u003cp-sidebar #sidebar2 [style]=\"{top: '60px', 'background-color': '#303030', color: '#d0d0d0'}\" [(visible)]=\"display\" position=\"right\" [baseZIndex]=\"997\" [modal]=\"false\"\u003e--\u003e\n\u003cdiv class=\"right-sidebar p-2\" *ngIf=\"display\"\u003e\n \n \n \u003cinput (keyup.enter)=\"makeCall(phone)\" (keyup)=\"keyUp(phone)\" pInputText [(ngModel)]=\"phone\" class=\"mb-1\" [ngModelOptions]=\"{standalone: true}\" \n \n *ngIf = \"1==1 || state \u0026\u0026 (state.name != 'ringing' \u0026\u0026 state.name != 'active' \u0026\u0026 state.name != 'early' \u0026\u0026 state.name != 'trying')\"\n \n /\u003e\n \u003cng-container\u003e\n \u003cdiv class=\"p-card row\" *ngFor=\"let c of c_calls_recent_found_out\"\u003e\n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e\n {{c.phone}}\n \u003c/div\u003e \n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e \n \u003cspan class=\"p-badge p-badge-info\"\u003e{{c.created_at}}\u003c/span\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \n \u003c/ng-container\u003e\n \n \u003cbutton [style]=\"{'backgroundColor':sessioninfo?.pause_type?.row_color}\" pTooltip=\"Нажмите, чтобы установить ваш статус присутствия\" tooltipPosition=\"left\" showDelay=\"1000\" pButton type=\"button\" class=\"p-button-secondary d-block mb-1\" (click)=\"setStatus()\"\u003e\u003cspan class=\"material-icons\"\u003eaccount_circle\u003c/span\u003e\u003c/button\u003e\n \n \u003cbutton pButton (click)=\"makeCall(phone)\" class=\"me-2 p-button-primary p-button-rounded p-button-outlined\" *ngIf = \"1==1 || state \u0026\u0026 (state.name != 'ringing' \u0026\u0026 state.name != 'active' \u0026\u0026 state.name != 'early' \u0026\u0026 state.name != 'trying')\"\u003e\u003cspan class=\"material-icons\"\u003ecall\u003c/span\u003e Позвонить\u003c/button\u003e\n \n \n \u003cdiv *ngFor=\"let call of calls\"\u003e\n \n \n\u003cp-dialog header=\"Переадресовать вызов\" [(visible)]=\"call.visibleTransferDialog\" [style]=\"{height: '30vw'}\"\u003e\n \u003cdiv class=\"row\" style=\"width:700px\"\u003e\n \u003cp-tabView styleClass=\"tabview-custom\"\u003e\n \n \u003cp-tabPanel\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-phone\"\u003e\u003c/i\u003e\n \u003cspan\u003eПереадресовать\u003c/span\u003e\n \u003c/ng-template\u003e\n \n \n\n \u003cp-button label=\"Переадресовать на последний набранный {{lastPhone}}\" (click)=\"transfer(call,lastPhone)\"\u003e\u003c/p-button\u003e\n \u003cdiv class=\"row\" *ngFor=\"let queue of queues\"\u003e\n \u003cdiv class=\"col\"\u003e\n \u003cp-button [label]=\"queue.title\" (click)=\"transfer(call,'6004'+queue.code)\"\u003e\u003c/p-button\u003e\n \u003c/div\u003e\n \u003c/div\u003e \n \n \n \n \u003c/p-tabPanel\u003e\n \n \u003cp-tabPanel\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-user\"\u003e\u003c/i\u003e\n \u003cspan\u003eНазначить перезвон\u003c/span\u003e\n \u003c/ng-template\u003e\n \n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col-3\" *ngFor=\"let user of transferToUsers\"\u003e\n \n \u003ca pButton (click)=\"recall(call,user)\"\u003e\n {{user.title}} {{user.ext_id$}}\n \u003c/a\u003e \n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/p-tabPanel\u003e\n \n \n \u003cp-tabPanel *ngIf=\"transferToUsers\"\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-user\"\u003e\u003c/i\u003e\n \u003cspan\u003eСотруднику\u003c/span\u003e\n \u003c/ng-template\u003e\n \n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col\"\u003e\n \u003cinput class=\"form-control\" placeholder=\"Введите имя\" [(ngModel)]=\"searchAgentModel\" (keyup)=\"searchAgents(searchAgentModel)\" /\u003e\n \u003c/div\u003e\n \u003c/div\u003e \n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col-3 mb-3\" *ngFor=\"let user of transferToUsers\"\u003e\n \u003cp-card\u003e\n \u003cdiv class=\"col\"\u003e\n \u003ca (click)=\"transfer(call,user.ext_id$code)\"\u003e\n {{user.title}}\n \u003c/a\u003e\n \u003c/div\u003e\n \u003cdiv class=\"col\"\u003e\n \u003ca (click)=\"transfer(call,user.ext_id$code)\"\u003e\n {{user.ext_id$}}\n \u003c/a\u003e\n \u003c/div\u003e\n \u003c/p-card\u003e \n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/p-tabPanel\u003e\n \n \u003c!--\n \u003cp-tabPanel\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-users\"\u003e\u003c/i\u003e\n \u003cspan\u003eВ Группу\u003c/span\u003e\n \u003c/ng-template\u003e\n \u003cp\u003edasdas\u003c/p\u003e\n \u003c/p-tabPanel\u003e\n \n --\u003e\n \n\t\n \n \u003cp-tabPanel\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-phone\"\u003e\u003c/i\u003e\n \u003cspan\u003eВнешний телефон\u003c/span\u003e\n \u003c/ng-template\u003e\n \n \u003ch5\u003eВведите номер телефона:\u003c/h5\u003e\n \u003cinput type=\"text\" pInputText [(ngModel)]=\"transferPhone\"/\u003e\n \u003cbr /\u003e\n \u003cp-button label=\"Переадресовать\" (click)=\"transfer(call,transferPhone)\"\u003e\u003c/p-button\u003e\n \n \n \u003c/p-tabPanel\u003e\n \n \u003cp-tabPanel\u003e\n \u003cng-template pTemplate = \"header\"\u003e\n \u003ci class=\"pi pi-reply\"\u003e\u003c/i\u003e\n \u003cspan\u003eМой телефон\u003c/span\u003e\n \u003c/ng-template\u003e\n \u003cp\u003edasdas\u003c/p\u003e\n \u003c/p-tabPanel\u003e \n \n\n \n \u003c/p-tabView\u003e\n \u003c/div\u003e\n\u003c/p-dialog\u003e\n\n \n \u003cdiv *ngIf=\"call \u0026\u0026 call.state \u0026\u0026 call.state.name \u0026\u0026 call.state.name!='destroy'\"\u003e \n \n \u003cdiv [ngSwitch]=\"call.state.name\"\u003e\n \u003cspan *ngSwitchCase=\"'trying'\"\u003eВызов {{call.destination_number}} \n \u003cp-progressBar mode=\"indeterminate\" [style]=\"{'height': '6px'}\"\u003e\u003c/p-progressBar\u003e\n \u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'new'\"\u003eНовый\u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'early'\"\u003eВызов {{phone}}\n \n \u003cp-progressBar mode=\"indeterminate\" [style]=\"{'height': '6px'}\"\u003e\u003c/p-progressBar\u003e\n \u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'hangup'\"\u003eВызов завершен.\u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'destroy'\"\u003eВызов завершен.\u003c/span\u003e\n \n \u003cspan *ngSwitchCase=\"'ringing'\"\u003eВходящий звонок...\u003cbr /\u003e{{call.params.caller_id_number}}\u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'active'\"\u003eТекущий звонок c \u003cbr /\u003e {{call.params.remote_caller_id_number || call.params.destination_number || call.params.caller_id_number}} \u003c/span\u003e\n \u003cspan *ngSwitchCase=\"'held'\"\u003eУдержан звонок с \u003cbr /\u003e {{call.params.remote_caller_id_number || call.params.destination_number || call.params.caller_id_number}} \u003c/span\u003e\n \u003cspan *ngSwitchDefault\u003estate = {{state.name}}\u003c/span\u003e\n\n \n \n\n \n \u003cbr/\u003e\n \n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col-4\" *ngFor=\"let p of ivr_path\"\u003e\n \u003cbutton pButton pRipple type=\"button\" class=\"p-button-outlined p-button-warning\"\u003e{{p.idx}}\u003c/button\u003e\n \n \u003c/div\u003e\n \u003c/div\u003e\n \n \u003cng-container *ngIf=\"call \u0026\u0026 call.cli_app_id \u0026\u0026 call.cli_app_subject\"\u003e\n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col\" style=\"padding-right:60px\"\u003e\n \n \u003cbutton pButton pRipple type=\"button\" class=\"p-button-outlined p-button-warning\"\u003e{{call.cli_app_subject}}\u003c/button\u003e\n \u003cbutton pButton pRipple type=\"button\" (click)=\"router.navigate(['c_cli_appdetails/'+call.cli_app_id + '/phone='+ (call.params.remote_caller_id_number || call.params.destination_number || call.params.caller_id_number)])\" class=\"p-button-outlined p-button-warning\"\u003eОТКРЫТЬ ЗАЯВКУ\u003c/button\u003e\n \u003c/div\u003e\n \u003c/div\u003e \n \u003c/ng-container\u003e \n \n \u003cng-container *ngIf=\"call \u0026\u0026 call.clients\"\u003e\n \u003cdiv class=\"p-card row\" *ngFor=\"let client of call.clients\"\u003e\n \u003cdiv class=\"col\" style=\"padding-right:60px\"\u003e\n \u003ca pButton class=\"mb-2\" (click)=\"router.navigate(['c_clidetails/'+client.id+'/phone='+ (call.params.remote_caller_id_number || call.params.destination_number || call.params.caller_id_number)])\"\u003e\u003cspan class=\"material-icons\"\u003eaccount_box\u003c/span\u003e\u003c/a\u003e\n {{client.name1}} {{client.name2}} {{client.name3}}\n \u003c/div\u003e\n \u003c/div\u003e \n \u003c/ng-container\u003e \n \u003cspan *ngFor=\"let user of users\"\u003e{{user.title}}\u003c/span\u003e\u003cbr/\u003e\n \n\n \u003c!--\u003cbutton pButton (click)=\"notify('title','body')\"\u003eNotify\u003c/button\u003e--\u003e\n \n \u003cbutton pButton (click)=\"answer(call)\" class=\"me-2 p-button-success p-button-rounded p-button-outlined\" *ngIf=\"call.state \u0026\u0026 call.state.name=='ringing'\"\u003e\u003cspan class=\"material-icons\"\u003ecall\u003c/span\u003e\u003c/button\u003e\n \u003cbutton pButton (click)=\"hangupCall(call)\" class=\"me-2 p-button-success p-button-rounded p-button-danger\" *ngIf=\"call.state \u0026\u0026 (call.state.name == 'trying' || call.state.name == 'active' || call.state.name == 'early' || call.state.name == 'ringing' )\"\u003e\u003cspan class=\"material-icons\"\u003ecall_end\u003c/span\u003e\u003c/button\u003e\n \n \n \n \u003cbutton pTooltip=\"Нажмите, чтобы сделать переадресацию текущего вызова\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"showTransferDialog(call)\" class=\"me-2 p-button-success p-button-rounded p-button-secondary\" *ngIf=\"call.state \u0026\u0026 call.state.name=='active'\"\u003e\u003cspan class=\"material-icons\"\u003ephone_forwarded\u003c/span\u003e\u003c/button\u003e\n \n \n \u003cbutton pTooltip=\"Нажмите, чтобы включить микрофон\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"setMute(call,'on')\" class=\"me-2 p-button-danger p-button-rounded p-button-secondary\" *ngIf=\"call.mute=='off' \u0026\u0026 call.state \u0026\u0026 call.state.name=='active'\"\u003e\u003cspan class=\"material-icons\"\u003emic_off\u003c/span\u003e \u003c/button\u003e\n \u003cbutton pTooltip=\"Нажмите, чтобы выключить микрофон\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"setMute(call,'off')\" class=\"me-2 p-button-success p-button-rounded p-button-secondary\" *ngIf=\"call.mute!='off' \u0026\u0026 call.state \u0026\u0026 call.state.name=='active'\"\u003e\u003cspan class=\"material-icons\"\u003emic\u003c/span\u003e \u003c/button\u003e\n \n\u003c!--\u003cbutton pTooltip=\"Нажмите, чтобы выключить микрофон\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"hold(call)\" class=\"me-2 p-button-danger p-button-rounded p-button-secondary\" *ngIf=\"call.state \u0026\u0026 call.state.name=='active'\"\u003e\u003cspan class=\"material-icons\"\u003emic_off\u003c/span\u003e\u003c/button\u003e\n \u003cbutton pTooltip=\"Нажмите, чтобы включить микрофон\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"unhold(call)\" class=\"me-2 p-button-success p-button-rounded p-button-secondary\" *ngIf=\"call.state \u0026\u0026 call.state.name=='held'\"\u003e\u003cspan class=\"material-icons\"\u003emic\u003c/span\u003e\u003c/button\u003e\n --\u003e\n \n \n \u003cdiv class=\"row\"\u003e\n \u003cdiv class=\"col text-center\"\u003e\n \u003cspan [id]=\"call.callID\"\u003e\u003c/span\u003e\n \u003c/div\u003e\n \u003c/div\u003e \n \n \n \u003c/div\u003e \n \n \u003c/div\u003e\n \u003c/div\u003e \n \n \u003cdiv class=\"row\" style=\"padding-right:60px;margin-top:20px\" *ngIf=\"activeCalls == 2\"\u003e\n \u003cdiv class=\"col text-center\"\u003e \n \u003cbutton pTooltip=\"Объединить 2 вызова\" tooltipPosition=\"top\" showDelay=\"1000\" pButton (click)=\"parkAndBridge()\" class=\"me-2 p-button-success p-button-rounded p-button-secondary\" *ngIf=\"1==1\"\u003eОбъединить\u003cspan class=\"material-icons\"\u003ecall_split\u003c/span\u003e\u003c/button\u003e\n \u003c/div\u003e\n \u003c/div\u003e \n \n\u003cdiv class=\"row p-2\"\u003e \n \u003cdiv\u003e\n \u003cp-accordion\u003e \n \u003cp-accordionTab\u003e\n \u003cng-template pTemplate=\"header\" *ngIf=\"c_calls_recent_out\"\u003eНабранные\u003c/ng-template\u003e\n \u003cng-template pTemplate=\"content\"\u003e\n \u003cdiv class=\"row\" *ngFor=\"let c of c_calls_recent_out\"\u003e\n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e\n {{c.phone}}\n \u003c/div\u003e \n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e \n \u003cspan class=\"p-badge p-badge-info\"\u003e{{c.created_at}}\u003c/span\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/ng-template\u003e\n \u003c/p-accordionTab\u003e \n \n \u003cp-accordionTab\u003e\n \u003cng-template pTemplate=\"header\" *ngIf=\"c_calls_recent_in\"\u003eПринятые\u003c/ng-template\u003e\n \u003cng-template pTemplate=\"content\"\u003e\n \u003cdiv class=\"row\" *ngFor=\"let c of c_calls_recent_in\"\u003e\n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e\n {{c.phone}}\n \u003c/div\u003e \n \u003cdiv class=\"col\" (click)=\"phone=c.phone\"\u003e \n \u003cspan class=\"p-badge p-badge-info\"\u003e{{c.created_at}}\u003c/span\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/ng-template\u003e\n \u003c/p-accordionTab\u003e \n \u003c/p-accordion\u003e \n \u003c/div\u003e\n\u003c/div\u003e\n \n \n \n\u003c!--\u003c/p-sidebar\u003e--\u003e\n\u003c/div\u003e\n\u003c!--\n\u003cdiv class=\"right-sidebar p-2\"\u003e\n \u003cbutton pTooltip=\"Нажмите, чтобы развернуть панель звонков\" tooltipPosition=\"left\" showDelay=\"3000\" pButton type=\"button\" class=\"d-block mb-1\" (click)=\"display = !display\"\u003e\u003cspan *ngIf=\"!display\" class=\"material-icons-sharp\"\u003earrow_back_ios\u003c/span\u003e\u003cspan *ngIf=\"display\" class=\"material-icons-sharp\"\u003earrow_forward_ios\u003c/span\u003e\u003c/button\u003e\n \u003cbutton [style]=\"{'backgroundColor':sessioninfo?.pause_type?.row_color}\" pTooltip=\"Нажмите, чтобы установить ваш статус присутствия\" tooltipPosition=\"left\" showDelay=\"1000\" pButton type=\"button\" class=\"p-button-secondary d-block mb-1\" (click)=\"setStatus()\"\u003e\u003cspan class=\"material-icons\"\u003eaccount_circle\u003c/span\u003e\u003c/button\u003e\n\u003c/div\u003e\n--\u003e","json":"const vm = this; \n\nconst {first} = rxjs;\nconst {map,take} = rxjs;\nconst {QueryOptions} = Models;\n\nreturn class GenClass extends vm.constructor {\n lastPhone = \"\";\n activeCalls = 0;\n needNotify = true;\n c_calls_recent_found_out = [];\n c_calls_recent_out = [];\n c_calls_recent_in = [];\n display = true;\n visibleTransferDialog = false;\n vertoHandle;\n state = {};\n state2 = {};//Дополнительный канал\n callParams = {};\n sec = 0;\n currentCall;\n calls = [];\n currentCall2;//Дополнительный канал\n clients;\n mute = \"on\";\n users;\n transferToUsers;\n ivr_path = [];\n agents = [];\n secInterval = 0;\n hangupPlayOn = false;\n transferPhone;callee_id_number\n \n transfer(call,number) {\n \n call.visibleTransferDialog = false;\n call.transfer(number);\n \n \n }\n \n recall(call,user) {\n \n //call.visibleTransferDialog = false;\n this.appComponent.bpRun('c_add_recall',{ 'phone':call.params.remote_caller_id_number, 'user_id': user.id });\n\n call.visibleTransferDialog = false;\n call.hangup();\n \n \n \n }\n \n \n ringPlay(){\n var audio = new Audio('/static/sounds/bell_ring2.wav');\n audio.play();\n } \n \n autoAnswerPlay(){\n var audio = new Audio('/static/sounds/autoanswer.wav');\n audio.play();\n } \n \n hangupPlay(){\n if (this.hangupPlayOn){\n var audio = new Audio('/static/sounds/call_end.wav');\n audio.play();\n }\n } \n \n addCall(d){\n \n \n if (this.calls.filter(call=\u003e{return call.callID==d.callID}).length==0){\n //this.unhold(d);\n this.calls.push(d);\n \n }\n }\n \n getQueues(text){\n let queueQuery = 'c_queue\u0026flt$fw$eq=1';\n this.queues = [];\n this.dbQueryService.getQuerySelect(queueQuery, '')\n .subscribe((resp) =\u003e {\n if (resp \u0026\u0026 resp.items){\n this.queues = resp.items;\n }\n });\n \n } \n searchAgents(text){\n let query = 'users\u0026flt$title$like=%25'+text+'%25\u0026flt$ext_id$in=(-2)';\n if (!text){\n query = \"users_my_lm_user_id\";\n }\n this.dbQueryService.getQuerySelect(query, '')\n .subscribe((resp) =\u003e {\n if (resp \u0026\u0026 resp.items){\n this.transferToUsers = resp.items;\n }\n });\n \n }\n \n \n get_c_calls_recent_in(text){\n \n this.dbQueryService.getQuerySelect('c_calls_recent_in_my\u0026orderBy=id\u0026orderDesc=true', '')\n .subscribe((resp) =\u003e {\n if (resp \u0026\u0026 resp.items){\n this.c_calls_recent_in = resp.items;\n }\n });\n \n } \n \n get_c_calls_recent_out(text){\n \n this.dbQueryService.getQuerySelect('c_calls_recent_out_my\u0026orderBy=id\u0026orderDesc=true', '')\n .subscribe((resp) =\u003e {\n if (resp \u0026\u0026 resp.items){\n this.c_calls_recent_out = resp.items;\n }\n });\n \n } \n \n \n set_c_calls_recent_in(phone){ \n this.dbQueryService.restapiPost(\"c_calls_recent_in_add\",{phone : phone})\n .pipe(first())\n .subscribe(items =\u003e {\n \t\t\t//d.clients = items.clients;\n \t\t\t//this.users = items.users;\n //this.text = \"\";\n //this.ivr_path = items.ivr_path;\n //this.notify(\"Входящий звонок\",d.params.caller_id_number);\n //this.needNotify=false;\n this.get_c_calls_recent_in();\n \n }); \n } \n \n set_c_calls_recent_out(phone){ \n this.dbQueryService.restapiPost(\"c_calls_recent_out_add\",{phone : phone})\n .pipe(first())\n .subscribe(items =\u003e {\n \t\t\t//d.clients = items.clients;\n \t\t\t//this.users = items.users;\n //this.text = \"\";\n //this.ivr_path = items.ivr_path;\n //this.notify(\"Входящий звонок\",d.params.caller_id_number);\n //this.needNotify=false;\n this.get_c_calls_recent_out();\n \n }); \n } \n\n showTransferDialog(call) {\n \n this.searchAgents(\"\");\n\n \n\n\n call.visibleTransferDialog = true;\n }\n \n onWSLogin = (verto, success) =\u003e {\n console.log('onWSLogin', success);\n if (success) {\n // At this point you're connected to the FreeSWITCH server and logged\n // in, ready to place a call to the conference, or run a test for the\n // user's bandwidth.\n }\n };\n \n onWSLogin2 = (verto, success) =\u003e {\n console.log('onWSLogin2', success);\n if (success) {\n // At this point you're connected to the FreeSWITCH server and logged\n // in, ready to place a call to the conference, or run a test for the\n // user's bandwidth.\n }\n }; \n \n \n onMessage = (verto, success) =\u003e {\n console.log('onMessage', verto, success);\n\n };\n \n onMessage2 = (verto, success) =\u003e {\n console.log('onMessage', verto, success);\n\n }; \n \n setTalking(value){\n this.dbQueryService.restapiPost(\"users_set_talking\",{talking : value})\n .pipe(first())\n .subscribe(items =\u003e {}); \n }\n \n getMyCallInfo(callID){\n \n this.dbQueryService.restapiPost(\"c_mycallinfo\",{callID : callID})\n .pipe(first())\n .subscribe(items =\u003e {\n this.sec = items.sec;\n \n this.clearSecInterval();\n \n this.secInterval = setInterval(() =\u003e {\n //this.callMethod(); \n this.sec++;\n //this.elementRef.nativeElement.querySelector('sec').innerHTML = this.sec;\n let mins = Math.floor(this.sec/60)+\"\"\n let secs = Math.floor(this.sec%60)+\"\"\n if (mins.length==\"1\"){ mins = \"0\"+mins}\n if (secs.length==\"1\"){ secs = \"0\"+secs}\n document.getElementById(callID).innerHTML = \"\u003ccode style='font-size:24pt'\u003e\"+mins+\":\"+secs+\"\u003c/code\u003e\"; \n //this.changeDetectorRef.detectChanges(); \n \n }, 1000); \n\n });\n \n \n }\n \n \n \n parkAndBridge(){\n\t \nlet activecalls = this.calls.filter(icall=\u003e{return (icall.state \u0026\u0026 (icall.state.name==\"active\" || icall.state.name==\"held\"))}).map(icall=\u003e{return icall.callID});\t \nthis.dbQueryService.restapiPost(\"c_uuid_park_and_bridge\",{calls : activecalls})\n .pipe(first())\n .subscribe(items =\u003e {\n //this.unhold(icall); this.hangupCall(icall)\n if (items.error_code!=0){\n this.messageService.add({severity:'danger', summary: items.error_text, detail: items.error_text }); \n }else{\n this.messageService.add({severity:'info', summary: \"Успешно переключено\", detail: \"Успешно переключено\" });\n }\n\t\t\t\t});\n }\n\n \n \n notify(title,body) {\n if (!this.needNotify){\n return;\n }\n let notify2 = {\n requireInteraction: true,\n body: body,\n // badge: '',\n //icon: '/assets/img/peopleavatars/face_1.svg',\n //image: '/assets/img/peopleavatars/face_2.svg',\n // data: [{ some_data: 1 }],\n // renotify: false,\n // silent: false,\n // sound: null, // ЗВУК\n // noscreen: false,\n // sticky: true,\n // dir: 'auto',\n // lang: 'ru-RU',\n // vibrate: true\n };\n this.messageService.add({severity:'info', summary: title, detail: body });\n /*this.notificationService.create('Входящий звонок', notify2).subscribe({\n next: x =\u003e {\n console.log(x);\n },\n error: error =\u003e {\n console.log(error);\n },\n complete: _ =\u003e {\n console.log('====');\n }\n });*/\n \n let notifications = new Notification(title+\" \"+body);\n }\n\n\n onDialogState = (d) =\u003e {\n \n \n this.get_c_calls_recent_out();\n \n if (d.lastState \u0026\u0026 d.lastState.name == 'answering' \u0026\u0026 d.state \u0026\u0026 d.state.name == 'active' \u0026\u0026 this.activeCalls==0){\n //this.calls.push(d);\n if (d.ext_autoanswer){\n this.autoAnswerPlay(); \n }\n this.addCall(d);\n }\n \n if (d.lastState \u0026\u0026 d.lastState.name == 'new' \u0026\u0026 d.state \u0026\u0026 d.state.name == 'ringing'){\n //this.calls.push(d);\n this.ringPlay();\n \n let activeCount = (this.calls.filter(call=\u003e{return call.state.name=='active'}).length);\n \n this.addCall(d);\n \n \n if (activeCount ==0 \u0026\u0026 this.sessioninfo.ext_autoanswer==\"1\"){\n \n d.ext_autoanswer = true; \n this.answer(d);\n }\n } \n \n this.activeCalls = this.calls.filter(call=\u003e{return (call.state \u0026\u0026 (call.state.name==\"active\" || call.state.name==\"held\"))}).length;\n\n this.currentCall = d;\n console.log('onDialogState', d);\n \n this.state = d.state;\n this.callParams = d.params;\n \n this.ivr_path = [];\n \n \n switch (d.state.name) {\n case \"trying\":\n //this.clearSecInterval();\n this.getMyCallInfo(d.callID);\n d.hangupPlayOn = true;\n break;\n case \"ringing\":\n this.display = true;\n this.clearSecInterval();\n \n \n \n this.dbQueryService.restapiPost(\"c_cli_by_phone\",{callID : d.callID, phone : d.params.caller_id_number})\n .pipe(first())\n .subscribe(items =\u003e {\n \t\t\td.clients = items.clients;\n \t\t\td.cli_app_id = items.cli_app_id;\n \t\t\td.cli_app_subject = items.cli_app_subject;\n \t\t\t\n \t\t\tthis.users = items.users;\n this.text = \"\";\n this.ivr_path = items.ivr_path;\n this.notify(\"Входящий звонок\",d.params.caller_id_number);\n this.needNotify=false;\n \n //this.dbQueryService.restapiPost(\"c_cli_app_take_to_work\",{id : d.cli_app_id})\n // .pipe(first())\n // .subscribe(items =\u003e {\n // this.router.navigate([\"c_cli_appdetails/\"+d.cli_app_id]);\n // }); \n \n });\n \n break;\n case \"answering\":\n this.needNotify=false;\n this.getMyCallInfo(d.callID);\n \n \n\n break;\n case \"active\":\n \n \n if (d.cli_app_id){\n \n this.dbQueryService.restapiPost(\"c_cli_app_take_to_work\",{id : d.cli_app_id})\n .pipe(first())\n .subscribe(items =\u003e {\n this.router.navigate([\"c_cli_appdetails/\"+d.cli_app_id]);\n });\n \n }else if (d.clients \u0026\u0026 d.clients.length == 1){\n this.router.navigate([\"c_clidetails/\"+d.clients[0].id+\"/phone=\"+ (d.params.remote_caller_id_number || d.params.destination_number || d.params.caller_id_number) ]);\n }\n \n d.hangupPlayOn = true;\n this.setTalking(1);\n this.getMyCallInfo(d.callID);\n break;\n case \"hangup\":\n this.needNotify=true;\n this.clearSecInterval();\n console.log(\"Call ended with cause: \" , d.cause,this.calls.filter(call=\u003e{return call.state.state=='active'}));\n if (this.calls.filter(call=\u003e{return call.state.name=='active'}).length\u003e0){\n console.log(\"logoff...\");\n setTimeout(_ =\u003e this.vertoHandle.logout(), 0); \n setTimeout(_ =\u003e this.initVerto(), 0); \n }\n \n if ( (this.session_roles.admin || this.session_roles.c_operator_cc) \u0026\u0026 !d.cli_app_id){\n this.appComponent.bpRun('cdr_end_call',{ 'call_id': d.callID })\n }\n break;\n case \"destroy\":\n // Some kind of client side cleanup...\n \n //this.vertoHandle.logout();\n //setTimeout(_ =\u003e this.initVerto(), 2000); \n this.setTalking(0);\n if (d.lastState \u0026\u0026 d.lastState.name==\"hangup\" \u0026\u0026 d.cause==\"NORMAL_CLEARING\"){\n //this.hangupPlay();\n if (d.hangupPlayOn){\n var audio = new Audio('/static/sounds/call_end.wav');\n audio.play();\n }\n }\n this.clearSecInterval();\n\n break;\n }\n };\n \n vertoCallbacks2 = {\n onDialogState: this.onDialogState2,\n onWSLogin: this.onWSLogin2,\n onMessage: this.onMessage2, \n \n };\n \n vertoCallbacks = {\n onDialogState: this.onDialogState,\n onWSLogin: this.onWSLogin,\n onMessage: this.onMessage,\n // Other callbacks...\n };\n \n ngAfterViewInit() {\n setTimeout(_ =\u003e this.initVerto(), 0);\n //setTimeout(_ =\u003e this.initVerto2(), 2000);\n \n \n Notification.requestPermission().then((permission) =\u003e {\n this.dbQueryService.restapiPost(\"c_notification_request\",{permission :permission})\n .pipe(first())\n .subscribe(items =\u003e {\n \n });\n \n \n\t });\n\t \n \n }\n \n clearSecInterval(){\n if (this.secInterval) {\n this.sec = 0; \n clearInterval(this.secInterval);\n } \n }\n \n \n \n ngOnInit(){\n this.get_c_calls_recent_out();\n this.get_c_calls_recent_in();\n this.getQueues();\n } \n \n ngOnDestroy(){\n this.clearSecInterval();\n }\n \n setStatus(){\n this.appComponent.bpRun(\"c_agent_set_status\",{});\n }\n \n initVerto() {\n \n console.log(\"initVerto\",this.sessioninfo)\n \n\n if (!this.sessioninfo){\n return;\n }\n \n this.calls = [];\n console.log(\"sessioninfo\",this.sessioninfo.ext_code)\n \n this.scriptsService.loadUrl('/jquery.min.js').then(x =\u003e { \n this.scriptsService.loadUrl('/jquery.json.min.js').then(x =\u003e { \n this.scriptsService.loadUrl('/jquery.verto.js').then(x =\u003e { \n this.scriptsService.loadUrl('/jquery.FSRTC.js').then(x =\u003e { \n this.scriptsService.loadUrl('/jquery.jsonrpcclient.js').then(x =\u003e { \n\n\n this.vertoHandle = new jQuery.verto({\n login: this.sessioninfo.ext_code+'@192.168.155.76',\n passwd: this.sessioninfo.ext_pwd,\n \n // As configured in verto.conf.xml on the server.\n socketUrl: 'wss://'+window.location.host+'/verto',\n // TODO: Where is this file, on the server? What is the base path?\n ringFile: '/static/sounds/bell_ring2.wav',\n // STUN/TURN server config, more than one is allowed.\n // Instead of an array of objects, you can also pass a Boolean value,\n // false disables STUN, true uses the default Google STUN servers.\n //url: 'stun:'+window.location.host,\n iceServers: [\n {\n \n 'url': 'turns:turn.cloud.damubpm.kz:5349',\n 'username': 'user',\n 'credential': 'user', \n //urls: \"turn:crm.cloud.damubpm.kz/turn1?transport=tcp\",\n \n },\n ],\n \n iceServers: true, \n //iceTransportPolicy:'relay',\n // These can be set per-call as well as per-login. They can also be set to\n // A specific device ID, or 'none' to disable that particular element of\n // the media flow.\n deviceParams: {\n // Set to 'none' to disable outbound audio.\n useMic: 'any',\n // Set to 'none' to disable inbound audio.\n useSpeak: 'any',\n // Set to 'none' to disable outbound video.\n useCamera: 'none',\n },\n // Optional Id of the HTML audio/video tag to be used for playing video/audio.\n // This can even be a function which will return an element id. (Use this as\n // function to create unique element for every new call specially when dealing\n // with multiple calls simultaneously to avoid conflicts between streams.\n // In this case, once call is finished, newly generated element will be\n // destroyed automatically)\n tag: \"audio\",\n // Below are some more advanced configuration parameters.\n // Google Chrome specific adjustments/filters for audio.\n // Official documentation is scant, best to try them out and see!\n //audioParams: {\n // googEchoCancellation: true,\n // googAutoGainControl: true,\n // googNoiseSuppression: true,\n // googHighpassFilter: true,\n // googTypingNoiseDetection: true,\n // googEchoCancellation2: false,\n // googAutoGainControl2: false,\n //},\n // Internal session ID used by Verto to track the call, eg. for call\n // recovery. A random one will be generated if none is provided, and,\n // it can be useful to provide a custom ID to store and reference for\n // other purposes.\n //sessid: sessid,\n }, this.vertoCallbacks);\n \n \n\n }); \n }); \n }); \n }); \n });\n \n \n\n \n }\n \n \n \n onCall() {\n if(this.display) {\n this.makeCall()\n }\n \n this.display = !this.display;\n }\n \n hold (call) {\n call.hold(); \n }; \n \n unhold (call) {\n call.unhold(); \n }; \n \n setMute (call,mute) {\n call.mute=mute;\n call.rtc.setMute(mute); \n };\n \n \n answer (call) {\n \n this.hangupPlayOn = true;\n\n //this.currentCall.media();\n call.answer();\n //this.unhold(call);\n this.set_c_calls_recent_in(call.params.caller_id_number);\n \n if (this.clients \u0026\u0026 this.clients.length\u003e0) {\n //location.href=\"c_clidetails/\"+this.clients[0].id; \n //this.router.navigate([\"c_clidetails/\"+this.clients[0].id])\n }\n \n };\n \n\n hangupCall (call) {\n \n \n this.hangupPlayOn = false;\n call.hangupPlayOn = false;\n call.hangup();\n \n if (this.calls.filter(call=\u003e{return call.state.name=='active'}).length\u003e0){\n //console.log(\"logoff...\");\n setTimeout(_ =\u003e this.vertoHandle.logout(), 0); \n setTimeout(_ =\u003e this.initVerto(), 0); \n }\n \n //this.vertoHandle.logout();\n //setTimeout(_ =\u003e this.initVerto(), 0);\n };\n \n keyUp(phone){\n this.c_calls_recent_found_out = [];\n \n if (!phone) { return} \n if (phone \u0026\u0026 phone.length\u003c5) { return} \n \n if (this.c_calls_recent_out){\n this.c_calls_recent_found_out =this.c_calls_recent_out.filter(call=\u003e{ return call.phone.includes(phone.substr(2)) });\n }\n //if (this.c_calls_recent_found_out \u0026\u0026 this.c_calls_recent_found_out.length\u003e0){\n // this.c_calls_recent_found_out=this.c_calls_recent_found_out[0];\n //}\n }\n makeCall(phone) {\n \n \n if (!phone) {\n alert(\"Введите номер телефона\")\n }\n \n phone = phone.replaceAll(\"-\",\"\");\n phone = phone.replaceAll(\"(\",\"\");\n phone = phone.replaceAll(\")\",\"\");\n phone = phone.replaceAll(\" \",\"\");\n \n phone = phone.trim();\n \n if (phone.length==10){\n phone = \"+7\"+phone;\n }\n \n if (phone.length==11 \u0026\u0026 phone.substr(0,1)==\"8\"){\n phone = \"+7\"+phone.substr(1,11);\n } \n \n if (phone.length==11){\n phone = \"+\"+phone;\n } \n \n \n this.display =true;\n console.log(\"makeCall\",phone);\n \n \n this.set_c_calls_recent_out(phone);\n this.lastPhone = phone;\n \n \n\n \n \n let call = this.vertoHandle.newCall({\n destination_number: phone,\n caller_id_name: this.sessioninfo.ext_code,\n caller_id_number: this.sessioninfo.ext_code,\n outgoingBandwidth: 'default',\n incomingBandwidth: 'default',\n useStereo: false,\n dedEnc: true,\n useVideo: false,\n useMic: 'any',\n useSpeak: 'any', \n userVariables: {\n email: 'test@test.com'\n },\n });\n \n //this.calls.push(call);\n \n //this.calls.forEach(call=\u003e{if (call.state \u0026\u0026 call.state.name==\"active\") { this.hold(call)}});\n this.calls.forEach(call=\u003e{if (call.state \u0026\u0026 call.state.name==\"active\") { this.setMute(call,'off')}});\n \n \n this.addCall(call);\n \n \n /*this.dbQueryService.restapiPost(\"c_cli_by_phone\",{callID : this.currentCall.callID, phone : phone})\n .pipe(first())\n .subscribe(items =\u003e {\n \t\t\tthis.clients = items.clients;\n \t\t\tthis.users = items.users;\n this.text = \"\";\n this.ivr_path = items.ivr_path;\n \n });*/\n \n \n };\n \n makeCall2(phone) {\n \n \n if (!phone) {\n alert(\"Введите номер телефона\")\n }\n \n phone = phone.replaceAll(\"-\",\"\");\n \n\n \n if (phone.length==10){\n phone = \"+7\"+phone;\n }\n \n if (phone.length==11 \u0026\u0026 phone.substr(0,1)==\"8\"){\n phone = \"+7\"+phone.substr(1,11);\n } \n \n if (phone.length==11){\n phone = \"+\"+phone;\n } \n \n \n this.display =true;\n console.log(\"makeCall2\",phone);\n \n \n\n \n \n \n \n \n\n \n \n }; \n \n\n}"}