mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Replace ngx-modialog with ng-bootstrap modals
This commit is contained in:
parent
4954de2a96
commit
e77d712afd
2
.vscode/settings.json
vendored
Normal file
2
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
6
config/bot.json
Normal file
6
config/bot.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"syncToken": "s22_2648_0_1_29_1_25_19_1",
|
||||||
|
"filter": null,
|
||||||
|
"appserviceUsers": {},
|
||||||
|
"appserviceTransactions": {}
|
||||||
|
}
|
6
config/bot.json.bak
Normal file
6
config/bot.json.bak
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"syncToken": "s3510138_39116385_25484_5602626_218935_269_119102_8310593_32",
|
||||||
|
"filter": null,
|
||||||
|
"appserviceUsers": {},
|
||||||
|
"appserviceTransactions": {}
|
||||||
|
}
|
BIN
config/dimension.db.bak
Normal file
BIN
config/dimension.db.bak
Normal file
Binary file not shown.
9
package-lock.json
generated
9
package-lock.json
generated
@ -11648,15 +11648,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
|
||||||
"integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
|
"integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
|
||||||
},
|
},
|
||||||
"ngx-modialog": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ngx-modialog/-/ngx-modialog-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-m6o7V01j97C/6GGQjNfxF96k6713G11Fs/S6RF7NbxRV3EUZsG0MqkDn2Q1fR0UEoaNqyKMDVDTya7N3hAnfPA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"tslib": "^1.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ngx-ui-switch": {
|
"ngx-ui-switch": {
|
||||||
"version": "12.0.1",
|
"version": "12.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ngx-ui-switch/-/ngx-ui-switch-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ngx-ui-switch/-/ngx-ui-switch-12.0.1.tgz",
|
||||||
|
@ -117,7 +117,6 @@
|
|||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"json-loader": "^0.5.7",
|
"json-loader": "^0.5.7",
|
||||||
"mini-css-extract-plugin": "^2.1.0",
|
"mini-css-extract-plugin": "^2.1.0",
|
||||||
"ngx-modialog": "^5.0.1",
|
|
||||||
"postcss-cssnext": "^3.1.0",
|
"postcss-cssnext": "^3.1.0",
|
||||||
"postcss-import": "^14.0.2",
|
"postcss-import": "^14.0.2",
|
||||||
"postcss-loader": "^6.1.1",
|
"postcss-loader": "^6.1.1",
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Add a new self-hosted IRC Bridge' | translate}}</h4>
|
||||||
<h4>{{'Add a new self-hosted IRC Bridge' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<p>{{'Self-hosted IRC bridges must have' | translate}}<code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
<p>{{'Self-hosted IRC bridges must have' | translate}}<code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Provisioning URL' | translate}}
|
{{'Provisioning URL' | translate}}
|
||||||
<span class="text-muted ">{{'The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.' | translate}}</span>
|
<span class="text-muted ">{{'The provisioning URL for the bridge. This is usually the same as the URL given in the registration. This API is not authenticated and should be treated with caution.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="http://localhost:9999"
|
placeholder="http://localhost:9999"
|
||||||
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service";
|
import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class AddSelfhostedIrcBridgeDialogContext extends BSModalContext {
|
export interface AddSelfhostedIrcBridgeDialogContextt {
|
||||||
|
isSaving: boolean;
|
||||||
|
provisionUrl: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./add-selfhosted.component.html",
|
templateUrl: "./add-selfhosted.component.html",
|
||||||
styleUrls: ["./add-selfhosted.component.scss"],
|
styleUrls: ["./add-selfhosted.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminIrcBridgeAddSelfhostedComponent implements ModalComponent<AddSelfhostedIrcBridgeDialogContext> {
|
export class AdminIrcBridgeAddSelfhostedComponent {
|
||||||
|
|
||||||
public isSaving = false;
|
public isSaving = false;
|
||||||
public provisionUrl: string;
|
public provisionUrl: string;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<AddSelfhostedIrcBridgeDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private ircApi: AdminIrcApiService,
|
private ircApi: AdminIrcApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
@ -28,7 +29,7 @@ export class AdminIrcBridgeAddSelfhostedComponent implements ModalComponent<AddS
|
|||||||
this.isSaving = true;
|
this.isSaving = true;
|
||||||
this.ircApi.newSelfhosted(this.provisionUrl).then(() => {
|
this.ircApi.newSelfhosted(this.provisionUrl).then(() => {
|
||||||
this.translate.get('IRC Bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('IRC Bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
|
@ -4,13 +4,12 @@ import { AdminIrcApiService } from "../../../shared/services/admin/admin-irc-api
|
|||||||
import { FE_Upstream } from "../../../shared/models/admin-responses";
|
import { FE_Upstream } from "../../../shared/models/admin-responses";
|
||||||
import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service";
|
import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service";
|
||||||
import { FE_IrcBridge } from "../../../shared/models/irc";
|
import { FE_IrcBridge } from "../../../shared/models/irc";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { AdminIrcBridgeNetworksComponent, IrcNetworksDialogContext } from "./networks/networks.component";
|
import { AdminIrcBridgeNetworksComponent, IrcNetworksDialogContext } from "./networks/networks.component";
|
||||||
import {
|
import {
|
||||||
AddSelfhostedIrcBridgeDialogContext,
|
|
||||||
AdminIrcBridgeAddSelfhostedComponent
|
AdminIrcBridgeAddSelfhostedComponent
|
||||||
} from "./add-selfhosted/add-selfhosted.component";
|
} from "./add-selfhosted/add-selfhosted.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./irc.component.html",
|
templateUrl: "./irc.component.html",
|
||||||
@ -28,7 +27,7 @@ export class AdminIrcBridgeComponent implements OnInit {
|
|||||||
constructor(private upstreamApi: AdminUpstreamApiService,
|
constructor(private upstreamApi: AdminUpstreamApiService,
|
||||||
private ircApi: AdminIrcApiService,
|
private ircApi: AdminIrcApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -94,23 +93,34 @@ export class AdminIrcBridgeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addSelfHostedBridge() {
|
public addSelfHostedBridge() {
|
||||||
this.modal.open(AdminIrcBridgeAddSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminIrcBridgeAddSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, AddSelfhostedIrcBridgeDialogContext)).result.then(() => {
|
});
|
||||||
this.reload().catch(err => {
|
selfhostedRef.result.then(() => {
|
||||||
|
try {
|
||||||
|
this.reload()
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update IRC bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update IRC bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public editNetworks(bridge: FE_IrcBridge) {
|
public editNetworks(bridge: FE_IrcBridge) {
|
||||||
this.modal.open(AdminIrcBridgeNetworksComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminIrcBridgeNetworksComponent, {
|
||||||
bridge: bridge,
|
backdrop: 'static',
|
||||||
|
|
||||||
isBlocking: true,
|
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, IrcNetworksDialogContext));
|
});
|
||||||
|
selfhostedRef.result.then(() => {
|
||||||
|
try {
|
||||||
|
this.reload()
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
this.translate.get('Failed to get an update IRC bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as IrcNetworksDialogContext;
|
||||||
|
selfhostedInstance.bridge = bridge;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{ bridge.upstreamId ? "matrix.org's" : "Self-hosted" }} IRC Bridge Networks</h4>
|
||||||
<h4>{{ bridge.upstreamId ? "matrix.org's" : "Self-hosted" }} IRC Bridge Networks</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<table class="table table-striped table-condensed table-bordered">
|
<table class="table table-striped table-condensed table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{'Network' | translate}}</th>
|
<th>{{'Network' | translate}}</th>
|
||||||
<th>{{'Enabled' | translate}}</th>
|
<th>{{'Enabled' | translate}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr *ngFor="let network of networks trackById">
|
<tr *ngFor="let network of networks trackById">
|
||||||
<td>{{ network.name }}</td>
|
<td>{{ network.name }}</td>
|
||||||
<td>
|
<td>
|
||||||
<ui-switch [checked]="network.isEnabled" size="small" [disabled]="isUpdating"
|
<ui-switch [checked]="network.isEnabled" size="small" [disabled]="isUpdating"
|
||||||
(change)="toggleNetwork(network)"></ui-switch>
|
(change)="toggleNetwork(network)"></ui-switch>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-outline-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { FE_IrcBridge } from "../../../../shared/models/irc";
|
import { FE_IrcBridge } from "../../../../shared/models/irc";
|
||||||
import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service";
|
import { AdminIrcApiService } from "../../../../shared/services/admin/admin-irc-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class IrcNetworksDialogContext extends BSModalContext {
|
export interface IrcNetworksDialogContext {
|
||||||
public bridge: FE_IrcBridge;
|
bridge: FE_IrcBridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface LocalNetwork {
|
interface LocalNetwork {
|
||||||
@ -22,19 +21,17 @@ interface LocalNetwork {
|
|||||||
templateUrl: "./networks.component.html",
|
templateUrl: "./networks.component.html",
|
||||||
styleUrls: ["./networks.component.scss"],
|
styleUrls: ["./networks.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminIrcBridgeNetworksComponent implements ModalComponent<IrcNetworksDialogContext> {
|
export class AdminIrcBridgeNetworksComponent {
|
||||||
|
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public bridge: FE_IrcBridge;
|
public bridge: FE_IrcBridge;
|
||||||
public networks: LocalNetwork[];
|
public networks: LocalNetwork[];
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<IrcNetworksDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private ircApi: AdminIrcApiService,
|
private ircApi: AdminIrcApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.bridge = dialog.context.bridge;
|
|
||||||
|
|
||||||
const networkIds = Object.keys(this.bridge.availableNetworks);
|
const networkIds = Object.keys(this.bridge.availableNetworks);
|
||||||
this.networks = networkIds.map(i => {
|
this.networks = networkIds.map(i => {
|
||||||
return {
|
return {
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'self-hosted Slack bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
||||||
<h4> {{'self-hosted Slack bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<p>
|
<p>
|
||||||
{{'Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.' | translate}}
|
{{'Self-hosted Slack bridges already have provisioning enabled. Be careful not to expose the API to the public internet.' | translate}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Provisioning URL' | translate}}
|
{{'Provisioning URL' | translate}}
|
||||||
<span class="text-muted ">{{'The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.' | translate}}</span>
|
<span class="text-muted ">{{'The provisioning URL for the bridge. This is usually the same as the URL your homeserver uses to communicate with the bridge.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="http://localhost:9000"
|
placeholder="http://localhost:9000"
|
||||||
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,34 +1,31 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { AdminSlackApiService } from "../../../../shared/services/admin/admin-slack-api.service";
|
import { AdminSlackApiService } from "../../../../shared/services/admin/admin-slack-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class ManageSelfhostedSlackBridgeDialogContext extends BSModalContext {
|
export interface ManageSelfhostedSlackBridgeDialogContext {
|
||||||
public provisionUrl: string;
|
provisionUrl: string;
|
||||||
public bridgeId: number;
|
bridgeId: number;
|
||||||
|
isAdding: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./manage-selfhosted.component.html",
|
templateUrl: "./manage-selfhosted.component.html",
|
||||||
styleUrls: ["./manage-selfhosted.component.scss"],
|
styleUrls: ["./manage-selfhosted.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent<ManageSelfhostedSlackBridgeDialogContext> {
|
export class AdminSlackBridgeManageSelfhostedComponent {
|
||||||
|
|
||||||
public isSaving = false;
|
public isSaving = false;
|
||||||
public provisionUrl: string;
|
public provisionUrl: string;
|
||||||
public bridgeId: number;
|
public bridgeId: number;
|
||||||
public isAdding = false;
|
public isAdding = true;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<ManageSelfhostedSlackBridgeDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private slackApi: AdminSlackApiService,
|
private slackApi: AdminSlackApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.provisionUrl = dialog.context.provisionUrl;
|
|
||||||
this.bridgeId = dialog.context.bridgeId;
|
|
||||||
this.isAdding = !this.bridgeId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public add() {
|
public add() {
|
||||||
@ -36,7 +33,7 @@ export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent
|
|||||||
if (this.isAdding) {
|
if (this.isAdding) {
|
||||||
this.slackApi.newSelfhosted(this.provisionUrl).then(() => {
|
this.slackApi.newSelfhosted(this.provisionUrl).then(() => {
|
||||||
this.translate.get('Slack bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Slack bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
@ -45,7 +42,7 @@ export class AdminSlackBridgeManageSelfhostedComponent implements ModalComponent
|
|||||||
} else {
|
} else {
|
||||||
this.slackApi.updateSelfhosted(this.bridgeId, this.provisionUrl).then(() => {
|
this.slackApi.updateSelfhosted(this.bridgeId, this.provisionUrl).then(() => {
|
||||||
this.translate.get('Slack bridge updated').subscribe((res: string) => this.toaster.pop("success", res));
|
this.translate.get('Slack bridge updated').subscribe((res: string) => this.toaster.pop("success", res));
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { FE_Upstream } from "../../../shared/models/admin-responses";
|
import { FE_Upstream } from "../../../shared/models/admin-responses";
|
||||||
import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service";
|
import { AdminUpstreamApiService } from "../../../shared/services/admin/admin-upstream-api.service";
|
||||||
import {
|
import {
|
||||||
@ -10,6 +9,7 @@ import {
|
|||||||
import { FE_SlackBridge } from "../../../shared/models/slack";
|
import { FE_SlackBridge } from "../../../shared/models/slack";
|
||||||
import { AdminSlackApiService } from "../../../shared/services/admin/admin-slack-api.service";
|
import { AdminSlackApiService } from "../../../shared/services/admin/admin-slack-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./slack.component.html",
|
templateUrl: "./slack.component.html",
|
||||||
@ -26,7 +26,7 @@ export class AdminSlackBridgeComponent implements OnInit {
|
|||||||
constructor(private slackApi: AdminSlackApiService,
|
constructor(private slackApi: AdminSlackApiService,
|
||||||
private upstreamApi: AdminUpstreamApiService,
|
private upstreamApi: AdminUpstreamApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -75,31 +75,38 @@ export class AdminSlackBridgeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addSelfHostedBridge() {
|
public addSelfHostedBridge() {
|
||||||
this.modal.open(AdminSlackBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminSlackBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: '',
|
selfhostedRef.result.then(() => {
|
||||||
}, ManageSelfhostedSlackBridgeDialogContext)).result.then(() => {
|
try {
|
||||||
this.reload().catch(err => {
|
this.reload()
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedSlackBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
public editBridge(bridge: FE_SlackBridge) {
|
public editBridge(bridge: FE_SlackBridge) {
|
||||||
this.modal.open(AdminSlackBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminSlackBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: bridge.provisionUrl,
|
selfhostedRef.result.then(() => {
|
||||||
bridgeId: bridge.id,
|
try {
|
||||||
}, ManageSelfhostedSlackBridgeDialogContext)).result.then(() => {
|
this.reload()
|
||||||
this.reload().catch(err => {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Slack bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedSlackBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = '';
|
||||||
|
selfhostedInstance.bridgeId = bridge.id;
|
||||||
|
selfhostedInstance.isAdding = !bridge.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,45 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'self-hosted Telegram bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
||||||
<h4> {{'self-hosted Telegram bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<p>{{'Self-hosted Telegram bridges must have' | translate}} <code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
<p>{{'Self-hosted Telegram bridges must have' | translate}} <code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Provisioning URL' | translate}}
|
{{'Provisioning URL' | translate}}
|
||||||
<span class="text-muted ">{{'The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.' | translate}}</span>
|
<span class="text-muted ">{{'The provisioning URL for the bridge. This is the public address for the bridge followed by the provisioning prefix given in the configuration.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="http://localhost:9999/_matrix/provision/v1"
|
placeholder="http://localhost:9999/_matrix/provision/v1"
|
||||||
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Shared Secret' | translate}}
|
{{'Shared Secret' | translate}}
|
||||||
<span class="text-muted ">{{'The shared secret defined in the configuration for provisioning.' | translate}}</span>
|
<span class="text-muted ">{{'The shared secret defined in the configuration for provisioning.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="some_secret_value"
|
placeholder="some_secret_value"
|
||||||
[(ngModel)]="sharedSecret" [disabled]="isSaving"/>
|
[(ngModel)]="sharedSecret" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Promote Telegram Puppeting' | translate}}
|
{{'Promote Telegram Puppeting' | translate}}
|
||||||
<span class="text-muted ">{{'If enabled, Dimension will recommend that users log in to their Telegram accounts.' | translate}}</span>
|
<span class="text-muted ">{{'If enabled, Dimension will recommend that users log in to their Telegram accounts.' | translate}}</span>
|
||||||
<ui-switch [checked]="allowTgPuppets" size="small" [disabled]="isSaving"
|
<ui-switch [checked]="allowTgPuppets" size="small" [disabled]="isSaving"
|
||||||
(change)="allowTgPuppets = !allowTgPuppets"></ui-switch>
|
(change)="allowTgPuppets = !allowTgPuppets"></ui-switch>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Promote Matrix Puppeting' | translate}}
|
{{'Promote Matrix Puppeting' | translate}}
|
||||||
<span class="text-muted ">{{'If enabled, Dimension will recommend that users log in to their Matrix accounts.' | translate}}</span>
|
<span class="text-muted ">{{'If enabled, Dimension will recommend that users log in to their Matrix accounts.' | translate}}</span>
|
||||||
<ui-switch [checked]="allowMxPuppets" size="small" [disabled]="isSaving"
|
<ui-switch [checked]="allowMxPuppets" size="small" [disabled]="isSaving"
|
||||||
(change)="allowMxPuppets = !allowMxPuppets"></ui-switch>
|
(change)="allowMxPuppets = !allowMxPuppets"></ui-switch>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="add()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,43 +1,37 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { AdminTelegramApiService } from "../../../../shared/services/admin/admin-telegram-api.service";
|
import { AdminTelegramApiService } from "../../../../shared/services/admin/admin-telegram-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class ManageSelfhostedTelegramBridgeDialogContext extends BSModalContext {
|
export interface ManageSelfhostedTelegramBridgeDialogContext {
|
||||||
public provisionUrl: string;
|
provisionUrl: string;
|
||||||
public sharedSecret: string;
|
sharedSecret: string;
|
||||||
public allowTgPuppets = false;
|
allowTgPuppets: boolean;
|
||||||
public allowMxPuppets = false;
|
allowMxPuppets: boolean;
|
||||||
public bridgeId: number;
|
bridgeId: number;
|
||||||
|
isAdding: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./manage-selfhosted.component.html",
|
templateUrl: "./manage-selfhosted.component.html",
|
||||||
styleUrls: ["./manage-selfhosted.component.scss"],
|
styleUrls: ["./manage-selfhosted.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminTelegramBridgeManageSelfhostedComponent implements ModalComponent<ManageSelfhostedTelegramBridgeDialogContext> {
|
export class AdminTelegramBridgeManageSelfhostedComponent {
|
||||||
|
|
||||||
public isSaving = false;
|
isSaving = false;
|
||||||
public provisionUrl: string;
|
provisionUrl: string;
|
||||||
public sharedSecret: string;
|
sharedSecret: string;
|
||||||
public allowTgPuppets = false;
|
allowTgPuppets = false;
|
||||||
public allowMxPuppets = false;
|
allowMxPuppets = false;
|
||||||
public bridgeId: number;
|
bridgeId: number;
|
||||||
public isAdding = false;
|
isAdding = true;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<ManageSelfhostedTelegramBridgeDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private telegramApi: AdminTelegramApiService,
|
private telegramApi: AdminTelegramApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.provisionUrl = dialog.context.provisionUrl;
|
|
||||||
this.sharedSecret = dialog.context.sharedSecret;
|
|
||||||
this.allowTgPuppets = dialog.context.allowTgPuppets;
|
|
||||||
this.allowMxPuppets = dialog.context.allowMxPuppets;
|
|
||||||
this.bridgeId = dialog.context.bridgeId;
|
|
||||||
this.isAdding = !this.bridgeId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public add() {
|
public add() {
|
||||||
@ -49,7 +43,7 @@ export class AdminTelegramBridgeManageSelfhostedComponent implements ModalCompon
|
|||||||
if (this.isAdding) {
|
if (this.isAdding) {
|
||||||
this.telegramApi.newSelfhosted(this.provisionUrl, this.sharedSecret, options).then(() => {
|
this.telegramApi.newSelfhosted(this.provisionUrl, this.sharedSecret, options).then(() => {
|
||||||
this.translate.get('Telegram bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Telegram bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
@ -58,7 +52,7 @@ export class AdminTelegramBridgeManageSelfhostedComponent implements ModalCompon
|
|||||||
} else {
|
} else {
|
||||||
this.telegramApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret, options).then(() => {
|
this.telegramApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret, options).then(() => {
|
||||||
this.translate.get('Telegram bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Telegram bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import {
|
import {
|
||||||
AdminTelegramBridgeManageSelfhostedComponent,
|
AdminTelegramBridgeManageSelfhostedComponent,
|
||||||
ManageSelfhostedTelegramBridgeDialogContext
|
ManageSelfhostedTelegramBridgeDialogContext
|
||||||
@ -8,6 +7,7 @@ import {
|
|||||||
import { FE_TelegramBridge } from "../../../shared/models/telegram";
|
import { FE_TelegramBridge } from "../../../shared/models/telegram";
|
||||||
import { AdminTelegramApiService } from "../../../shared/services/admin/admin-telegram-api.service";
|
import { AdminTelegramApiService } from "../../../shared/services/admin/admin-telegram-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./telegram.component.html",
|
templateUrl: "./telegram.component.html",
|
||||||
@ -21,7 +21,7 @@ export class AdminTelegramBridgeComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private telegramApi: AdminTelegramApiService,
|
constructor(private telegramApi: AdminTelegramApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -40,19 +40,23 @@ export class AdminTelegramBridgeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addSelfHostedBridge() {
|
public addSelfHostedBridge() {
|
||||||
this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: '',
|
selfhostedRef.result.then(() => {
|
||||||
sharedSecret: '',
|
try {
|
||||||
allowPuppets: false,
|
this.reload()
|
||||||
}, ManageSelfhostedTelegramBridgeDialogContext)).result.then(() => {
|
} catch (err) {
|
||||||
this.reload().catch(err => {
|
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
})
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedTelegramBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = '';
|
||||||
|
selfhostedInstance.sharedSecret = '';
|
||||||
|
selfhostedInstance.allowMxPuppets = false;
|
||||||
|
selfhostedInstance.allowTgPuppets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEnabledFeaturesString(bridge: FE_TelegramBridge): string {
|
public getEnabledFeaturesString(bridge: FE_TelegramBridge): string {
|
||||||
@ -63,20 +67,24 @@ export class AdminTelegramBridgeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public editBridge(bridge: FE_TelegramBridge) {
|
public editBridge(bridge: FE_TelegramBridge) {
|
||||||
this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminTelegramBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: bridge.provisionUrl,
|
selfhostedRef.result.then(() => {
|
||||||
sharedSecret: bridge.sharedSecret,
|
try {
|
||||||
allowTgPuppets: bridge.options ? bridge.options.allowTgPuppets : false,
|
this.reload()
|
||||||
allowMxPuppets: bridge.options ? bridge.options.allowMxPuppets : false,
|
} catch (err) {
|
||||||
bridgeId: bridge.id,
|
|
||||||
}, ManageSelfhostedTelegramBridgeDialogContext)).result.then(() => {
|
|
||||||
this.reload().catch(err => {
|
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Telegram bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
})
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedTelegramBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = bridge.provisionUrl;
|
||||||
|
selfhostedInstance.sharedSecret = bridge.sharedSecret;
|
||||||
|
selfhostedInstance.allowMxPuppets = bridge.options?.allowTgPuppets || false;
|
||||||
|
selfhostedInstance.allowTgPuppets = bridge.options?.allowMxPuppets || false;
|
||||||
|
selfhostedInstance.bridgeId = bridge.id;
|
||||||
|
selfhostedInstance.isAdding = !bridge.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'self-hosted webhook bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
||||||
<h4> {{'self-hosted webhook bridge' | translate}} ({{ isAdding ? "Add a new" : "Edit" }})</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<p>{{'Self-hosted webhook bridges must have' | translate}} <code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
<p>{{'Self-hosted webhook bridges must have' | translate}} <code>{{'provisioning' | translate}}</code> {{'enabled in the configuration.' | translate}}</p>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Provisioning URL' | translate}}
|
{{'Provisioning URL' | translate}}
|
||||||
<span class="text-muted ">{{'The public URL for the bridge.' | translate}}</span>
|
<span class="text-muted ">{{'The public URL for the bridge.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="https://webhooks.example.org:9000/"
|
placeholder="https://webhooks.example.org:9000/"
|
||||||
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
[(ngModel)]="provisionUrl" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Shared Secret' | translate}}
|
{{'Shared Secret' | translate}}
|
||||||
<span class="text-muted ">{{'The provisioning secret defined in the configuration.' | translate}}</span>
|
<span class="text-muted ">{{'The provisioning secret defined in the configuration.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="some_secret_value"
|
placeholder="some_secret_value"
|
||||||
[(ngModel)]="sharedSecret" [disabled]="isSaving"/>
|
[(ngModel)]="sharedSecret" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="add()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,39 +1,37 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { AdminWebhooksApiService } from "../../../../shared/services/admin/admin-webhooks-api.service";
|
import { AdminWebhooksApiService } from "../../../../shared/services/admin/admin-webhooks-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class ManageSelfhostedWebhooksBridgeDialogContext extends BSModalContext {
|
export interface ManageSelfhostedWebhooksBridgeDialogContext {
|
||||||
public provisionUrl: string;
|
provisionUrl: string;
|
||||||
public sharedSecret: string;
|
sharedSecret: string;
|
||||||
public allowTgPuppets = false;
|
allowTgPuppets: boolean;
|
||||||
public allowMxPuppets = false;
|
allowMxPuppets: boolean;
|
||||||
public bridgeId: number;
|
bridgeId: number;
|
||||||
|
isAdding: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./manage-selfhosted.component.html",
|
templateUrl: "./manage-selfhosted.component.html",
|
||||||
styleUrls: ["./manage-selfhosted.component.scss"],
|
styleUrls: ["./manage-selfhosted.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalComponent<ManageSelfhostedWebhooksBridgeDialogContext> {
|
export class AdminWebhooksBridgeManageSelfhostedComponent {
|
||||||
|
|
||||||
public isSaving = false;
|
public isSaving = false;
|
||||||
public provisionUrl: string;
|
public provisionUrl: '';
|
||||||
public sharedSecret: string;
|
public sharedSecret: '';
|
||||||
|
public allowTgPuppets = false;
|
||||||
|
public allowMxPuppets = false;
|
||||||
public bridgeId: number;
|
public bridgeId: number;
|
||||||
public isAdding = false;
|
public isAdding = true;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<ManageSelfhostedWebhooksBridgeDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private webhooksApi: AdminWebhooksApiService,
|
private webhooksApi: AdminWebhooksApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.provisionUrl = dialog.context.provisionUrl;
|
|
||||||
this.sharedSecret = dialog.context.sharedSecret;
|
|
||||||
this.bridgeId = dialog.context.bridgeId;
|
|
||||||
this.isAdding = !this.bridgeId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public add() {
|
public add() {
|
||||||
@ -41,7 +39,7 @@ export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalCompon
|
|||||||
if (this.isAdding) {
|
if (this.isAdding) {
|
||||||
this.webhooksApi.newSelfhosted(this.provisionUrl, this.sharedSecret).then(() => {
|
this.webhooksApi.newSelfhosted(this.provisionUrl, this.sharedSecret).then(() => {
|
||||||
this.translate.get('Webhook bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Webhook bridge added').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
@ -50,7 +48,7 @@ export class AdminWebhooksBridgeManageSelfhostedComponent implements ModalCompon
|
|||||||
} else {
|
} else {
|
||||||
this.webhooksApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret).then(() => {
|
this.webhooksApi.updateSelfhosted(this.bridgeId, this.provisionUrl, this.sharedSecret).then(() => {
|
||||||
this.translate.get('Webhook bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Webhook bridge updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import {
|
import {
|
||||||
AdminWebhooksBridgeManageSelfhostedComponent,
|
AdminWebhooksBridgeManageSelfhostedComponent,
|
||||||
ManageSelfhostedWebhooksBridgeDialogContext
|
ManageSelfhostedWebhooksBridgeDialogContext
|
||||||
@ -8,6 +7,7 @@ import {
|
|||||||
import { FE_WebhooksBridge } from "../../../shared/models/webhooks";
|
import { FE_WebhooksBridge } from "../../../shared/models/webhooks";
|
||||||
import { AdminWebhooksApiService } from "../../../shared/services/admin/admin-webhooks-api.service";
|
import { AdminWebhooksApiService } from "../../../shared/services/admin/admin-webhooks-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./webhooks.component.html",
|
templateUrl: "./webhooks.component.html",
|
||||||
@ -21,7 +21,7 @@ export class AdminWebhooksBridgeComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private webhooksApi: AdminWebhooksApiService,
|
constructor(private webhooksApi: AdminWebhooksApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -40,34 +40,42 @@ export class AdminWebhooksBridgeComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addSelfHostedBridge() {
|
public addSelfHostedBridge() {
|
||||||
this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: '',
|
selfhostedRef.result.then(() => {
|
||||||
sharedSecret: '',
|
try {
|
||||||
allowPuppets: false,
|
this.reload()
|
||||||
}, ManageSelfhostedWebhooksBridgeDialogContext)).result.then(() => {
|
} catch (err) {
|
||||||
this.reload().catch(err => {
|
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedWebhooksBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = '';
|
||||||
|
selfhostedInstance.sharedSecret = '';
|
||||||
|
selfhostedInstance.allowMxPuppets = false;
|
||||||
|
selfhostedInstance.allowTgPuppets = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public editBridge(bridge: FE_WebhooksBridge) {
|
public editBridge(bridge: FE_WebhooksBridge) {
|
||||||
this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminWebhooksBridgeManageSelfhostedComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
provisionUrl: bridge.provisionUrl,
|
selfhostedRef.result.then(() => {
|
||||||
sharedSecret: bridge.sharedSecret,
|
try {
|
||||||
bridgeId: bridge.id,
|
this.reload()
|
||||||
}, ManageSelfhostedWebhooksBridgeDialogContext)).result.then(() => {
|
} catch (err) {
|
||||||
this.reload().catch(err => {
|
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an update Webhooks bridge list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as ManageSelfhostedWebhooksBridgeDialogContext;
|
||||||
|
selfhostedInstance.provisionUrl = bridge.provisionUrl;
|
||||||
|
selfhostedInstance.sharedSecret = bridge.sharedSecret
|
||||||
|
selfhostedInstance.bridgeId = bridge.id;
|
||||||
|
selfhostedInstance.isAdding = !bridge.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,55 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{ isAdding ? "Add a new" : "Edit" }} {{ 'custom bot' | translate}}</h4>
|
||||||
<h4>{{ isAdding ? "Add a new" : "Edit" }} {{ 'custom bot' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
User ID
|
User ID
|
||||||
<span class="text-muted">{{'The user ID that Dimension will invite to rooms.' | translate}}</span>
|
<span class="text-muted">{{'The user ID that Dimension will invite to rooms.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="@yourbot:example.org"
|
placeholder="@yourbot:example.org"
|
||||||
[(ngModel)]="bot.userId" [disabled]="isSaving" (blur)="loadProfile()"/>
|
[(ngModel)]="bot.userId" [disabled]="isSaving" (blur)="loadProfile()"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
Description
|
Description
|
||||||
<span class="text-muted ">{{'A few words here will help people understand what the bot does.' | translate}}</span>
|
<span class="text-muted ">{{'A few words here will help people understand what the bot does.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="Does awesome things"
|
placeholder="Does awesome things"
|
||||||
[(ngModel)]="bot.description" [disabled]="isSaving"/>
|
[(ngModel)]="bot.description" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Display Name' | translate}}
|
{{'Display Name' | translate}}
|
||||||
<span class="text-muted ">{{'This is the name Dimension will use to tell users which bot this is.' | translate}}</span>
|
<span class="text-muted ">{{'This is the name Dimension will use to tell users which bot this is.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="Cool Bot"
|
placeholder="Cool Bot"
|
||||||
[(ngModel)]="bot.name" [disabled]="isSaving"/>
|
[(ngModel)]="bot.name" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
Avatar URL
|
Avatar URL
|
||||||
<span class="text-muted ">{{'This can either be an MXC URI or a plain URL.' | translate}}</span>
|
<span class="text-muted ">{{'This can either be an MXC URI or a plain URL.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="mxc://example.org/C00lAvat4r"
|
placeholder="mxc://example.org/C00lAvat4r"
|
||||||
[(ngModel)]="bot.avatarUrl" [disabled]="isSaving"/>
|
[(ngModel)]="bot.avatarUrl" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
Access Token
|
Access Token
|
||||||
<span class="text-muted ">{{'This is used by Dimension to force the bot to leave the room when the user removes the bot.' | translate}}
|
<span class="text-muted ">{{'This is used by Dimension to force the bot to leave the room when the user removes the bot.' | translate}}
|
||||||
<a href="https://t2bot.io/docs/access_tokens/" target="_blank">{{'Learn more about access tokens.' | translate}}</a>.
|
<a href="https://t2bot.io/docs/access_tokens/" target="_blank">{{'Learn more about access tokens.' | translate}}</a>.
|
||||||
</span>
|
</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="MDaX..."
|
placeholder="MDaX..."
|
||||||
[(ngModel)]="bot.accessToken" [disabled]="isSaving"/>
|
[(ngModel)]="bot.accessToken" [disabled]="isSaving"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="add()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="add()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i>{{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,34 +1,32 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { FE_CustomSimpleBot, FE_UserProfile } from "../../../shared/models/admin-responses";
|
import { FE_CustomSimpleBot, FE_UserProfile } from "../../../shared/models/admin-responses";
|
||||||
import { AdminCustomSimpleBotsApiService } from "../../../shared/services/admin/admin-custom-simple-bots-api.service";
|
import { AdminCustomSimpleBotsApiService } from "../../../shared/services/admin/admin-custom-simple-bots-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
export class AddCustomBotDialogContext extends BSModalContext {
|
export interface AddCustomBotDialogContext {
|
||||||
bot: FE_CustomSimpleBot;
|
bot: FE_CustomSimpleBot;
|
||||||
|
isAdding: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./add.component.html",
|
templateUrl: "./add.component.html",
|
||||||
styleUrls: ["./add.component.scss"],
|
styleUrls: ["./add.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminAddCustomBotComponent implements ModalComponent<AddCustomBotDialogContext> {
|
export class AdminAddCustomBotComponent {
|
||||||
|
|
||||||
public bot: FE_CustomSimpleBot;
|
public bot = <FE_CustomSimpleBot>{};
|
||||||
public isAdding = false;
|
public isAdding = true;
|
||||||
public isSaving = false;
|
public isSaving = false;
|
||||||
|
|
||||||
private lastProfile: FE_UserProfile;
|
private lastProfile: FE_UserProfile;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<AddCustomBotDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private botApi: AdminCustomSimpleBotsApiService,
|
private botApi: AdminCustomSimpleBotsApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.bot = this.dialog.context.bot || <FE_CustomSimpleBot>{};
|
|
||||||
this.isAdding = !this.dialog.context.bot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadProfile() {
|
public loadProfile() {
|
||||||
@ -89,7 +87,7 @@ export class AdminAddCustomBotComponent implements ModalComponent<AddCustomBotDi
|
|||||||
|
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
this.translate.get('Bot updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Bot updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -2,9 +2,9 @@ import { Component } from "@angular/core";
|
|||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { FE_CustomSimpleBot } from "../../shared/models/admin-responses";
|
import { FE_CustomSimpleBot } from "../../shared/models/admin-responses";
|
||||||
import { AdminCustomSimpleBotsApiService } from "../../shared/services/admin/admin-custom-simple-bots-api.service";
|
import { AdminCustomSimpleBotsApiService } from "../../shared/services/admin/admin-custom-simple-bots-api.service";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { AddCustomBotDialogContext, AdminAddCustomBotComponent } from "./add/add.component";
|
import { AddCustomBotDialogContext, AdminAddCustomBotComponent } from "./add/add.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./custom-bots.component.html",
|
templateUrl: "./custom-bots.component.html",
|
||||||
@ -18,7 +18,7 @@ export class AdminCustomBotsComponent {
|
|||||||
|
|
||||||
constructor(private botApi: AdminCustomSimpleBotsApiService,
|
constructor(private botApi: AdminCustomSimpleBotsApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
|
|
||||||
@ -36,29 +36,36 @@ export class AdminCustomBotsComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public addBot() {
|
public addBot() {
|
||||||
this.modal.open(AdminAddCustomBotComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminAddCustomBotComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, AddCustomBotDialogContext)).result.then(() => {
|
});
|
||||||
this.reload().catch(err => {
|
selfhostedRef.result.then(() => {
|
||||||
|
try {
|
||||||
|
this.reload()
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public editBot(bot: FE_CustomSimpleBot) {
|
public editBot(bot: FE_CustomSimpleBot) {
|
||||||
this.modal.open(AdminAddCustomBotComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminAddCustomBotComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
|
});
|
||||||
bot: bot,
|
selfhostedRef.result.then(() => {
|
||||||
}, AddCustomBotDialogContext)).result.then(() => {
|
try {
|
||||||
this.reload().catch(err => {
|
this.reload()
|
||||||
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Failed to get an updated bot list').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as AddCustomBotDialogContext;
|
||||||
|
selfhostedInstance.bot = bot;
|
||||||
|
selfhostedInstance.isAdding = !bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
public toggleBot(bot: FE_CustomSimpleBot) {
|
public toggleBot(bot: FE_CustomSimpleBot) {
|
||||||
|
@ -2,12 +2,11 @@ import { Component } from "@angular/core";
|
|||||||
import { AdminApiService } from "../../shared/services/admin/admin-api.service";
|
import { AdminApiService } from "../../shared/services/admin/admin-api.service";
|
||||||
import { FE_DimensionConfig } from "../../shared/models/admin-responses";
|
import { FE_DimensionConfig } from "../../shared/models/admin-responses";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import {
|
import {
|
||||||
AdminLogoutConfirmationDialogComponent,
|
AdminLogoutConfirmationDialogComponent,
|
||||||
LogoutConfirmationDialogContext
|
|
||||||
} from "./logout-confirmation/logout-confirmation.component";
|
} from "./logout-confirmation/logout-confirmation.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./home.component.html",
|
templateUrl: "./home.component.html",
|
||||||
@ -20,7 +19,7 @@ export class AdminHomeComponent {
|
|||||||
|
|
||||||
constructor(private adminApi: AdminApiService,
|
constructor(private adminApi: AdminApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
adminApi.getConfig().then(config => {
|
adminApi.getConfig().then(config => {
|
||||||
@ -30,16 +29,18 @@ export class AdminHomeComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public logoutAll(): void {
|
public logoutAll(): void {
|
||||||
this.modal.open(AdminLogoutConfirmationDialogComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminLogoutConfirmationDialogComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static'
|
||||||
}, LogoutConfirmationDialogContext)).result.then(() => {
|
});
|
||||||
this.adminApi.logoutAll().then(() => {
|
selfhostedRef.result.then(async () => {
|
||||||
|
try {
|
||||||
|
await this.adminApi.logoutAll();
|
||||||
this.translate.get('Everyone has been logged out').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Everyone has been logged out').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.config.sessionInfo.numTokens = 0;
|
this.config.sessionInfo.numTokens = 0;
|
||||||
}).catch(err => {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.translate.get('Error logging everyone out').subscribe((res: string) => {this.toaster.pop("error", res); });
|
this.translate.get('Error logging everyone out').subscribe((res: string) => {this.toaster.pop("error", res); });
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Logout confirmation' | translate}}</h4>
|
||||||
<h4>{{'Logout confirmation' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<p>
|
<p>
|
||||||
{{'Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.' | translate}}
|
{{'Logging everyone out will disable all known login tokens for Dimension and upstream integration managers. Most clients will automatically re-register for a login token behind the scenes, similar to how a login token was first acquired.' | translate}}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="dialog.dismiss()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.dismiss()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="logout everyone" class="btn btn-danger btn-sm">
|
<button type="button" (click)="modal.close()" title="logout everyone" class="btn btn-danger btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Logout Everyone' | translate}}
|
<i class="far fa-times-circle"></i> {{'Logout Everyone' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
|
|
||||||
export class LogoutConfirmationDialogContext extends BSModalContext {
|
export interface LogoutConfirmationDialogContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./logout-confirmation.component.html",
|
templateUrl: "./logout-confirmation.component.html",
|
||||||
styleUrls: ["./logout-confirmation.component.scss"],
|
styleUrls: ["./logout-confirmation.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminLogoutConfirmationDialogComponent implements ModalComponent<LogoutConfirmationDialogContext> {
|
export class AdminLogoutConfirmationDialogComponent {
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<LogoutConfirmationDialogContext>) {
|
constructor(public modal: NgbActiveModal) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@ import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-
|
|||||||
import { AdminNebApiService } from "../../../shared/services/admin/admin-neb-api.service";
|
import { AdminNebApiService } from "../../../shared/services/admin/admin-neb-api.service";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { ActivatedRoute, Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import {
|
import {
|
||||||
AdminNebAppserviceConfigComponent,
|
AdminNebAppserviceConfigComponent,
|
||||||
AppserviceConfigDialogContext
|
AppserviceConfigDialogContext
|
||||||
} from "../appservice-config/appservice-config.component";
|
} from "../appservice-config/appservice-config.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -26,9 +26,9 @@ export class AdminAddSelfhostedNebComponent {
|
|||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;{
|
||||||
}
|
}
|
||||||
|
|
||||||
public save(): void {
|
public save(): void {
|
||||||
@ -37,12 +37,14 @@ export class AdminAddSelfhostedNebComponent {
|
|||||||
return this.nebApi.newAppserviceConfiguration(this.adminUrl, appservice);
|
return this.nebApi.newAppserviceConfiguration(this.adminUrl, appservice);
|
||||||
}).then(neb => {
|
}).then(neb => {
|
||||||
this.translate.get('New go-neb created').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('New go-neb created').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({
|
|
||||||
neb: neb,
|
|
||||||
|
|
||||||
isBlocking: true,
|
const selfhostedRef = this.modal.open(AdminNebAppserviceConfigComponent, {
|
||||||
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, AppserviceConfigDialogContext)).result.then(() => this.router.navigate(["../.."], {relativeTo: this.activatedRoute}));
|
});
|
||||||
|
selfhostedRef.result.then(() => this.router.navigate(["../.."], {relativeTo: this.activatedRoute}));
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as AppserviceConfigDialogContext;
|
||||||
|
selfhostedInstance.neb = neb;
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.isSaving = false;
|
this.isSaving = false;
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'go-neb appservice configuration' | translate}}</h4>
|
||||||
<h4>{{'go-neb appservice configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="isLoading">
|
<div class="modal-body" *ngif="isLoading">
|
||||||
<my-spinner></my-spinner>
|
<my-spinner></my-spinner>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="!isLoading">
|
<div class="modal-body" *ngif="!isLoading">
|
||||||
{{'Copy and paste this configuration to' | translate}} <code>appservice-{{appservice.id}}.yaml</code>
|
{{'Copy and paste this configuration to' | translate}} <code>appservice-{{appservice.id}}.yaml</code>
|
||||||
{{'on your homeserver and register it as an application service.' | translate}}
|
{{'on your homeserver and register it as an application service.' | translate}}
|
||||||
<br/>
|
<br/>
|
||||||
<pre>{{appserviceConfig}}</pre>
|
<pre>{{appserviceConfig}}</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer" *ngIf="!isLoading">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="dialog.close()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="test()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<i class="fa fa-exchange-alt"></i> {{'Test Configuration' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="test()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="fa fa-exchange-alt"></i> {{'Test Configuration' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,32 +1,29 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { FE_Appservice, FE_NebConfiguration } from "../../../shared/models/admin-responses";
|
import { FE_Appservice, FE_NebConfiguration } from "../../../shared/models/admin-responses";
|
||||||
import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-appservice-api.service";
|
import { AdminAppserviceApiService } from "../../../shared/services/admin/admin-appservice-api.service";
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
export class AppserviceConfigDialogContext extends BSModalContext {
|
export interface AppserviceConfigDialogContext {
|
||||||
public neb: FE_NebConfiguration;
|
neb: FE_NebConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./appservice-config.component.html",
|
templateUrl: "./appservice-config.component.html",
|
||||||
styleUrls: ["./appservice-config.component.scss"],
|
styleUrls: ["./appservice-config.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminNebAppserviceConfigComponent implements ModalComponent<AppserviceConfigDialogContext> {
|
export class AdminNebAppserviceConfigComponent {
|
||||||
|
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public neb: FE_NebConfiguration;
|
public neb: FE_NebConfiguration;
|
||||||
public appservice: FE_Appservice;
|
public appservice: FE_Appservice;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<AppserviceConfigDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminAppserviceApi: AdminAppserviceApiService,
|
private adminAppserviceApi: AdminAppserviceApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.neb = dialog.context.neb;
|
|
||||||
|
|
||||||
this.adminAppserviceApi.getAppservice(this.neb.appserviceId).then(appservice => {
|
this.adminAppserviceApi.getAppservice(this.neb.appserviceId).then(appservice => {
|
||||||
this.appservice = appservice;
|
this.appservice = appservice;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { FE_NebConfiguration } from "../../../shared/models/admin-responses";
|
import { FE_NebConfiguration } from "../../../shared/models/admin-responses";
|
||||||
import { FE_Integration } from "../../../shared/models/integration";
|
import { FE_Integration } from "../../../shared/models/integration";
|
||||||
|
|
||||||
export class NebBotConfigurationDialogContext extends BSModalContext {
|
export interface NebBotConfigurationDialogContext {
|
||||||
public integration: FE_Integration;
|
integration: FE_Integration;
|
||||||
public neb: FE_NebConfiguration;
|
neb: FE_NebConfiguration;
|
||||||
}
|
}
|
@ -1,33 +1,32 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Giphy Configuration' | translate}}</h4>
|
||||||
<h4>{{'Giphy Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="isLoading">
|
<div class="modal-body" *ngIf="isLoading">
|
||||||
<my-spinner></my-spinner>
|
<my-spinner></my-spinner>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="!isLoading">
|
<div class="modal-body" *ngIf="!isLoading">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Api Key' | translate}}
|
{{'Api Key' | translate}}
|
||||||
<span class="text-muted ">{{'The API key from' | translate}} <a href="https://developers.giphy.com/" target="_blank">developers.giphy.com</a>.</span>
|
<span class="text-muted ">{{'The API key from' | translate}} <a href="https://developers.giphy.com/" target="_blank">developers.giphy.com</a>.</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_api_key_here"
|
placeholder="your_api_key_here"
|
||||||
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Image Size' | translate}}
|
{{'Image Size' | translate}}
|
||||||
<span class="text-muted ">{{'GIFs can be large, and sometimes it is more desirable to have them downsized.' | translate}}</span>
|
<span class="text-muted ">{{'GIFs can be large, and sometimes it is more desirable to have them downsized.' | translate}}</span>
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" [(ngModel)]="config.use_downsized" [disabled]="isUpdating"/>
|
<input type="checkbox" [(ngModel)]="config.use_downsized" [disabled]="isUpdating"/>
|
||||||
{{'Use downsized images' | translate}}
|
{{'Use downsized images' | translate}}
|
||||||
</label>
|
</label>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer" *ngIf="!isLoading">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { NebBotConfigurationDialogContext } from "../config-context";
|
|
||||||
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
||||||
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
||||||
import { FE_Integration } from "../../../../shared/models/integration";
|
import { FE_Integration } from "../../../../shared/models/integration";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface GiphyConfig {
|
interface GiphyConfig {
|
||||||
api_key: string;
|
api_key: string;
|
||||||
@ -16,7 +15,7 @@ interface GiphyConfig {
|
|||||||
templateUrl: "./giphy.component.html",
|
templateUrl: "./giphy.component.html",
|
||||||
styleUrls: ["./giphy.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./giphy.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminNebGiphyConfigComponent implements ModalComponent<NebBotConfigurationDialogContext>, OnInit {
|
export class AdminNebGiphyConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
@ -24,13 +23,11 @@ export class AdminNebGiphyConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
public integration: FE_Integration;
|
public integration: FE_Integration;
|
||||||
public neb: FE_NebConfiguration;
|
public neb: FE_NebConfiguration;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<NebBotConfigurationDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminNebApi: AdminNebApiService,
|
private adminNebApi: AdminNebApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.neb = dialog.context.neb;
|
|
||||||
this.integration = dialog.context.integration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
@ -47,7 +44,7 @@ export class AdminNebGiphyConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
||||||
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Google Configuration' | translate}}</h4>
|
||||||
<h4>{{'Google Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="isLoading">
|
<div class="modal-body" *ngIf="isLoading">
|
||||||
<my-spinner></my-spinner>
|
<my-spinner></my-spinner>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="!isLoading">
|
<div class="modal-body" *ngIf="!isLoading">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Api Key' | translate}}
|
{{'Api Key' | translate}}
|
||||||
<span class="text-muted ">{{'The API key for your Google Application.' | translate}}</span>
|
<span class="text-muted ">{{'The API key for your Google Application.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_api_key_here"
|
placeholder="your_api_key_here"
|
||||||
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
Search Engine ID
|
{{'Search Engine ID' | translate}}
|
||||||
<span class="text-muted ">{{'The search engine ID' | translate}}</span>
|
<span class="text-muted ">{{'The search engine ID' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_cx_id_here"
|
placeholder="your_cx_id_here"
|
||||||
[(ngModel)]="config.cx" [disabled]="isUpdating"/>
|
[(ngModel)]="config.cx" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer" *ngIf="!isLoading">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { NebBotConfigurationDialogContext } from "../config-context";
|
|
||||||
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
||||||
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
||||||
import { FE_Integration } from "../../../../shared/models/integration";
|
import { FE_Integration } from "../../../../shared/models/integration";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface GoogleConfig {
|
interface GoogleConfig {
|
||||||
api_key: string;
|
api_key: string;
|
||||||
@ -16,7 +15,7 @@ interface GoogleConfig {
|
|||||||
templateUrl: "./google.component.html",
|
templateUrl: "./google.component.html",
|
||||||
styleUrls: ["./google.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./google.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminNebGoogleConfigComponent implements ModalComponent<NebBotConfigurationDialogContext>, OnInit {
|
export class AdminNebGoogleConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
@ -24,13 +23,11 @@ export class AdminNebGoogleConfigComponent implements ModalComponent<NebBotConfi
|
|||||||
public integration: FE_Integration;
|
public integration: FE_Integration;
|
||||||
public neb: FE_NebConfiguration;
|
public neb: FE_NebConfiguration;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<NebBotConfigurationDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminNebApi: AdminNebApiService,
|
private adminNebApi: AdminNebApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.neb = dialog.context.neb;
|
|
||||||
this.integration = dialog.context.integration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
@ -47,7 +44,7 @@ export class AdminNebGoogleConfigComponent implements ModalComponent<NebBotConfi
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
||||||
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Guggy Configuration' | translate}}</h4>
|
||||||
<h4>{{'Guggy Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="isLoading">
|
<div class="modal-body" *ngIf="isLoading">
|
||||||
<my-spinner></my-spinner>
|
<my-spinner></my-spinner>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="!isLoading">
|
<div class="modal-body" *ngIf="!isLoading">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Api Key' | translate}}
|
{{'Api Key' | translate}}
|
||||||
<span class="text-muted ">{{'The API key for' | translate}} <a href="http://docs.guggy.com/" target="_blank">Guggy's API</a>.</span>
|
<span class="text-muted ">{{'The API key for' | translate}} <a href="http://docs.guggy.com/" target="_blank">Guggy's API</a>.</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_api_key_here"
|
placeholder="your_api_key_here"
|
||||||
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
[(ngModel)]="config.api_key" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer" *ngIf="!isLoading">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { NebBotConfigurationDialogContext } from "../config-context";
|
|
||||||
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
||||||
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
||||||
import { FE_Integration } from "../../../../shared/models/integration";
|
import { FE_Integration } from "../../../../shared/models/integration";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface GuggyConfig {
|
interface GuggyConfig {
|
||||||
api_key: string;
|
api_key: string;
|
||||||
@ -15,7 +14,7 @@ interface GuggyConfig {
|
|||||||
templateUrl: "./guggy.component.html",
|
templateUrl: "./guggy.component.html",
|
||||||
styleUrls: ["./guggy.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./guggy.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminNebGuggyConfigComponent implements ModalComponent<NebBotConfigurationDialogContext>, OnInit {
|
export class AdminNebGuggyConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
@ -23,13 +22,11 @@ export class AdminNebGuggyConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
public integration: FE_Integration;
|
public integration: FE_Integration;
|
||||||
public neb: FE_NebConfiguration;
|
public neb: FE_NebConfiguration;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<NebBotConfigurationDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminNebApi: AdminNebApiService,
|
private adminNebApi: AdminNebApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.neb = dialog.context.neb;
|
|
||||||
this.integration = dialog.context.integration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
@ -46,7 +43,7 @@ export class AdminNebGuggyConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
||||||
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -1,32 +1,31 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Imgur Configuration' | translate}}</h4>
|
||||||
<h4>{{'Imgur Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="isLoading">
|
<div class="modal-body" *ngIf="isLoading">
|
||||||
<my-spinner></my-spinner>
|
<my-spinner></my-spinner>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" *ngIf="!isLoading">
|
<div class="modal-body" *ngIf="!isLoading">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Client ID' | translate}}
|
{{'Client ID' | translate}}
|
||||||
<span class="text-muted ">{{'The client ID of your' | translate}} <a href="https://apidocs.imgur.com/" target="_blank">{{'Imgur Application' | translate}}</a>.</span>
|
<span class="text-muted ">{{'The client ID of your' | translate}} <a href="https://apidocs.imgur.com/" target="_blank">{{'Imgur Application' | translate}}</a>.</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_client_id"
|
placeholder="your_client_id"
|
||||||
[(ngModel)]="config.client_id" [disabled]="isUpdating"/>
|
[(ngModel)]="config.client_id" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Client Secret' | translate}}
|
{{'Client Secret' | translate}}
|
||||||
<span class="text-muted ">{{'The client secret of your' | translate}} <a href="https://apidocs.imgur.com/" target="_blank">{{'Imgur Application' | translate}}</a>.</span>
|
<span class="text-muted ">{{'The client secret of your' | translate}} <a href="https://apidocs.imgur.com/" target="_blank">{{'Imgur Application' | translate}}</a>.</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="your_client_secret"
|
placeholder="your_client_secret"
|
||||||
[(ngModel)]="config.client_secret" [disabled]="isUpdating"/>
|
[(ngModel)]="config.client_secret" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer" *ngIf="!isLoading">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { NebBotConfigurationDialogContext } from "../config-context";
|
|
||||||
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
import { AdminNebApiService } from "../../../../shared/services/admin/admin-neb-api.service";
|
||||||
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
import { FE_NebConfiguration } from "../../../../shared/models/admin-responses";
|
||||||
import { FE_Integration } from "../../../../shared/models/integration";
|
import { FE_Integration } from "../../../../shared/models/integration";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface ImgurConfig {
|
interface ImgurConfig {
|
||||||
client_id: string;
|
client_id: string;
|
||||||
@ -16,7 +15,7 @@ interface ImgurConfig {
|
|||||||
templateUrl: "./imgur.component.html",
|
templateUrl: "./imgur.component.html",
|
||||||
styleUrls: ["./imgur.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./imgur.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminNebImgurConfigComponent implements ModalComponent<NebBotConfigurationDialogContext>, OnInit {
|
export class AdminNebImgurConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
@ -24,13 +23,11 @@ export class AdminNebImgurConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
public integration: FE_Integration;
|
public integration: FE_Integration;
|
||||||
public neb: FE_NebConfiguration;
|
public neb: FE_NebConfiguration;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<NebBotConfigurationDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminNebApi: AdminNebApiService,
|
private adminNebApi: AdminNebApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.neb = dialog.context.neb;
|
|
||||||
this.integration = dialog.context.integration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
@ -47,7 +44,7 @@ export class AdminNebImgurConfigComponent implements ModalComponent<NebBotConfig
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
this.adminNebApi.setIntegrationConfiguration(this.neb.id, this.integration.type, this.config).then(() => {
|
||||||
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Configuration updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -5,14 +5,13 @@ import { ActivatedRoute } from "@angular/router";
|
|||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { FE_Integration } from "../../../shared/models/integration";
|
import { FE_Integration } from "../../../shared/models/integration";
|
||||||
import { NEB_HAS_CONFIG, NEB_IS_COMPLEX } from "../../../shared/models/neb";
|
import { NEB_HAS_CONFIG, NEB_IS_COMPLEX } from "../../../shared/models/neb";
|
||||||
import { ContainerContent, Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { AdminNebGiphyConfigComponent } from "../config/giphy/giphy.component";
|
import { AdminNebGiphyConfigComponent } from "../config/giphy/giphy.component";
|
||||||
import { NebBotConfigurationDialogContext } from "../config/config-context";
|
import { NebBotConfigurationDialogContext } from "../config/config-context";
|
||||||
import { AdminNebGuggyConfigComponent } from "../config/guggy/guggy.component";
|
import { AdminNebGuggyConfigComponent } from "../config/guggy/guggy.component";
|
||||||
import { AdminNebGoogleConfigComponent } from "../config/google/google.component";
|
import { AdminNebGoogleConfigComponent } from "../config/google/google.component";
|
||||||
import { AdminNebImgurConfigComponent } from "../config/imgur/imgur.component";
|
import { AdminNebImgurConfigComponent } from "../config/imgur/imgur.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./edit.component.html",
|
templateUrl: "./edit.component.html",
|
||||||
@ -30,7 +29,7 @@ export class AdminEditNebComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
constructor(private nebApi: AdminNebApiService,
|
constructor(private nebApi: AdminNebApiService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
@ -87,7 +86,7 @@ export class AdminEditNebComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public editBot(bot: FE_Integration) {
|
public editBot(bot: FE_Integration) {
|
||||||
let component: ContainerContent;
|
let component;
|
||||||
|
|
||||||
if (bot.type === "giphy") component = AdminNebGiphyConfigComponent;
|
if (bot.type === "giphy") component = AdminNebGiphyConfigComponent;
|
||||||
if (bot.type === "guggy") component = AdminNebGuggyConfigComponent;
|
if (bot.type === "guggy") component = AdminNebGuggyConfigComponent;
|
||||||
@ -95,13 +94,13 @@ export class AdminEditNebComponent implements OnInit, OnDestroy {
|
|||||||
if (bot.type === "imgur") component = AdminNebImgurConfigComponent;
|
if (bot.type === "imgur") component = AdminNebImgurConfigComponent;
|
||||||
|
|
||||||
if (!component) throw new Error("No config component for " + bot.type);
|
if (!component) throw new Error("No config component for " + bot.type);
|
||||||
this.modal.open(component, overlayConfigFactory({
|
const nebBotRef = this.modal.open(component, {
|
||||||
neb: this.nebConfig,
|
backdrop: 'static',
|
||||||
integration: bot,
|
|
||||||
|
|
||||||
isBlocking: true,
|
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, NebBotConfigurationDialogContext));
|
});
|
||||||
|
const nebBotInstance = nebBotRef.componentInstance as NebBotConfigurationDialogContext;
|
||||||
|
nebBotInstance.neb = this.nebConfig;
|
||||||
|
nebBotInstance.integration = bot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadNeb(nebId: number) {
|
private loadNeb(nebId: number) {
|
||||||
|
@ -9,8 +9,8 @@ import {
|
|||||||
AdminNebAppserviceConfigComponent,
|
AdminNebAppserviceConfigComponent,
|
||||||
AppserviceConfigDialogContext
|
AppserviceConfigDialogContext
|
||||||
} from "./appservice-config/appservice-config.component";
|
} from "./appservice-config/appservice-config.component";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./neb.component.html",
|
templateUrl: "./neb.component.html",
|
||||||
@ -31,7 +31,7 @@ export class AdminNebComponent {
|
|||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
|
|
||||||
@ -77,12 +77,12 @@ export class AdminNebComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public showAppserviceConfig(neb: FE_NebConfiguration) {
|
public showAppserviceConfig(neb: FE_NebConfiguration) {
|
||||||
this.modal.open(AdminNebAppserviceConfigComponent, overlayConfigFactory({
|
const selfhostedRef = this.modal.open(AdminNebAppserviceConfigComponent, {
|
||||||
neb: neb,
|
backdrop: 'static',
|
||||||
|
|
||||||
isBlocking: true,
|
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, AppserviceConfigDialogContext));
|
});
|
||||||
|
const selfhostedInstance = selfhostedRef.componentInstance as AppserviceConfigDialogContext;
|
||||||
|
selfhostedInstance.neb = neb;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getEnabledBotsString(neb: FE_NebConfiguration): string {
|
public getEnabledBotsString(neb: FE_NebConfiguration): string {
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">Sticker Pack: {{ pack.displayName }}</h4>
|
||||||
<h4>Sticker Pack: {{ pack.displayName }}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<div class="sticker" *ngFor="let sticker of pack.stickers trackById">
|
<div class="sticker" *ngFor="let sticker of pack.stickers trackById">
|
||||||
<img [src]="getThumbnailUrl(sticker.thumbnail.mxc, 120, 120)" width="120" height="120"/>
|
<img [src]="getThumbnailUrl(sticker.thumbnail.mxc, 120, 120)" width="120" height="120"/>
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
<span class="name">{{ sticker.name }}</span>
|
<span class="name">{{ sticker.name }}</span>
|
||||||
<span class="description">{{ sticker.description }}</span>
|
<span class="description">{{ sticker.description }}</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
</div>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<div class="modal-footer">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<button type="button" class="btn btn-outline-secondary" (click)="modal.close()"><i class="far fa-times-circle"></i> {{'Close' | translate}}</button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { FE_StickerPack } from "../../../shared/models/integration";
|
import { FE_StickerPack } from "../../../shared/models/integration";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { MediaService } from "../../../shared/services/media.service";
|
import { MediaService } from "../../../shared/services/media.service";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
export class StickerPackPreviewDialogContext extends BSModalContext {
|
export class StickerPackPreviewMoadlInstance {
|
||||||
public pack: FE_StickerPack;
|
public pack: FE_StickerPack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,12 +11,12 @@ export class StickerPackPreviewDialogContext extends BSModalContext {
|
|||||||
templateUrl: "./preview.component.html",
|
templateUrl: "./preview.component.html",
|
||||||
styleUrls: ["./preview.component.scss"],
|
styleUrls: ["./preview.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminStickerPackPreviewComponent implements ModalComponent<StickerPackPreviewDialogContext> {
|
export class AdminStickerPackPreviewComponent {
|
||||||
|
|
||||||
public pack: FE_StickerPack;
|
pack: FE_StickerPack;
|
||||||
|
|
||||||
|
constructor(public modal: NgbActiveModal, private media: MediaService) {
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<StickerPackPreviewDialogContext>, private media: MediaService) {
|
|
||||||
this.pack = dialog.context.pack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public getThumbnailUrl(mxc: string, width: number, height: number, method: "crop" | "scale" = "scale"): string {
|
public getThumbnailUrl(mxc: string, width: number, height: number, method: "crop" | "scale" = "scale"): string {
|
||||||
|
@ -2,8 +2,8 @@ import { Component, OnInit } from "@angular/core";
|
|||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { FE_StickerPack } from "../../shared/models/integration";
|
import { FE_StickerPack } from "../../shared/models/integration";
|
||||||
import { AdminStickersApiService } from "../../shared/services/admin/admin-stickers-api-service";
|
import { AdminStickersApiService } from "../../shared/services/admin/admin-stickers-api-service";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
import { AdminStickerPackPreviewComponent, StickerPackPreviewMoadlInstance } from "./preview/preview.component";
|
||||||
import { AdminStickerPackPreviewComponent, StickerPackPreviewDialogContext } from "./preview/preview.component";
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -20,7 +20,7 @@ export class AdminStickerPacksComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(private adminStickers: AdminStickersApiService,
|
constructor(private adminStickers: AdminStickersApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -50,12 +50,10 @@ export class AdminStickerPacksComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public previewStickers(pack: FE_StickerPack) {
|
public previewStickers(pack: FE_StickerPack) {
|
||||||
this.modal.open(AdminStickerPackPreviewComponent, overlayConfigFactory({
|
const modalRef = this.modal.open(AdminStickerPackPreviewComponent, { size: 'lg' });
|
||||||
pack: pack,
|
const previewInstance = modalRef.componentInstance as StickerPackPreviewMoadlInstance;
|
||||||
|
|
||||||
isBlocking: false,
|
previewInstance.pack = pack;
|
||||||
size: 'lg',
|
|
||||||
}, StickerPackPreviewDialogContext));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public startTelegramImport() {
|
public startTelegramImport() {
|
||||||
|
@ -4,12 +4,11 @@ import { AdminTermsApiService } from "../../../shared/services/admin/admin-terms
|
|||||||
import { ActivatedRoute, Router } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
|
import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic';
|
||||||
import ISO6391 from "iso-639-1";
|
import ISO6391 from "iso-639-1";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import {
|
import {
|
||||||
AdminTermsNewEditPublishDialogComponent,
|
AdminTermsNewEditPublishDialogComponent,
|
||||||
AdminTermsNewEditPublishDialogContext
|
|
||||||
} from "./publish/publish.component";
|
} from "./publish/publish.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface ILanguage {
|
interface ILanguage {
|
||||||
name: string,
|
name: string,
|
||||||
@ -67,7 +66,7 @@ export class AdminNewEditTermsComponent implements OnInit {
|
|||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
private modal: Modal,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -119,11 +118,11 @@ export class AdminNewEditTermsComponent implements OnInit {
|
|||||||
url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/draft`,
|
url: `${window.location.origin}/widgets/terms/${this.shortcode}/en/draft`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const termsEditRef = this.modal.open(AdminTermsNewEditPublishDialogComponent, {
|
||||||
this.modal.open(AdminTermsNewEditPublishDialogComponent, overlayConfigFactory({
|
backdrop: 'static',
|
||||||
isBlocking: true,
|
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
}, AdminTermsNewEditPublishDialogContext)).result.then(async (val) => {
|
});
|
||||||
|
termsEditRef.result.then(async (val) => {
|
||||||
if (!val) return; // closed without publish
|
if (!val) return; // closed without publish
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Publish policy' | translate}}</h4>
|
||||||
<h4>{{'Publish policy' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Version number' | translate}}
|
{{'Version number' | translate}}
|
||||||
<span class="text-muted ">{{'The version number of this policy' | translate}}</span>
|
<span class="text-muted ">{{'The version number of this policy' | translate}}</span>
|
||||||
<input type="text" class="form-control" placeholder="eg: 1.1.0" [(ngModel)]="version"/>
|
<input type="text" class="form-control" placeholder="eg: 1.1.0" [(ngModel)]="version"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="publish()" title="close" class="btn btn-primary btn-sm">
|
<button type="button" (click)="publish()" title="close" class="btn btn-primary btn-sm">
|
||||||
<i class="fas fa-upload"></i> {{'Publish' | translate}}
|
<i class="fas fa-upload"></i> {{'Publish' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="save" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
export class AdminTermsNewEditPublishDialogContext extends BSModalContext {
|
export interface AdminTermsNewEditPublishDialogContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./publish.component.html",
|
templateUrl: "./publish.component.html",
|
||||||
styleUrls: ["./publish.component.scss"],
|
styleUrls: ["./publish.component.scss"],
|
||||||
})
|
})
|
||||||
export class AdminTermsNewEditPublishDialogComponent implements ModalComponent<AdminTermsNewEditPublishDialogContext> {
|
export class AdminTermsNewEditPublishDialogComponent {
|
||||||
|
|
||||||
public version: string;
|
public version: string;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<AdminTermsNewEditPublishDialogContext>, private toaster: ToasterService, public translate: TranslateService) {
|
constructor(public modal: NgbActiveModal, private toaster: ToasterService, public translate: TranslateService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public publish() {
|
public publish() {
|
||||||
@ -23,6 +22,6 @@ export class AdminTermsNewEditPublishDialogComponent implements ModalComponent<A
|
|||||||
this.translate.get('Please enter a version number').subscribe((res: string) => {this.toaster.pop("warning", res); });
|
this.translate.get('Please enter a version number').subscribe((res: string) => {this.toaster.pop("warning", res); });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.dialog.close(this.version);
|
this.modal.close(this.version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Etherpad Widget Configuration' | translate}}</h4>
|
||||||
<h4>{{'Etherpad Widget Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Default Pad URL Template' | translate}}
|
{{'Default Pad URL Template' | translate}}
|
||||||
<span class="text-muted ">{{'$padName and $roomId will be replaced during creation to help create a unique pad URL.' | translate}}</span>
|
<span class="text-muted ">{{'$padName and $roomId will be replaced during creation to help create a unique pad URL.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="https://scalar.vector.im/etherpad/p/$padName_$roomId"
|
placeholder="https://scalar.vector.im/etherpad/p/$padName_$roomId"
|
||||||
[(ngModel)]="widget.options.defaultUrl" [disabled]="isUpdating"/>
|
[(ngModel)]="widget.options.defaultUrl" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,27 +1,29 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FE_EtherpadWidget } from "../../../shared/models/integration";
|
import { FE_EtherpadWidget } from "../../../shared/models/integration";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { WidgetConfigDialogContext } from "../widgets.component";
|
|
||||||
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./etherpad.component.html",
|
templateUrl: "./etherpad.component.html",
|
||||||
styleUrls: ["./etherpad.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./etherpad.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminWidgetEtherpadConfigComponent implements ModalComponent<WidgetConfigDialogContext> {
|
export class AdminWidgetEtherpadConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public widget: FE_EtherpadWidget;
|
public widget: FE_EtherpadWidget;
|
||||||
private originalWidget: FE_EtherpadWidget;
|
private originalWidget = <FE_EtherpadWidget>{};
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<WidgetConfigDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private adminIntegrationsApi: AdminIntegrationsApiService,
|
private adminIntegrationsApi: AdminIntegrationsApiService,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.originalWidget = dialog.context.widget;
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.originalWidget = this.widget;
|
||||||
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +32,7 @@ export class AdminWidgetEtherpadConfigComponent implements ModalComponent<Widget
|
|||||||
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
||||||
this.originalWidget.options = this.widget.options;
|
this.originalWidget.options = this.widget.options;
|
||||||
this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -1,35 +1,34 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Jitsi Widget Configuration' | translate}}</h4>
|
||||||
<h4>{{'Jitsi Widget Configuration' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Jitsi Domain' | translate}}
|
{{'Jitsi Domain' | translate}}
|
||||||
<span class="text-muted ">{{'This is the domain that is used to host the conference.' | translate}}</span>
|
<span class="text-muted ">{{'This is the domain that is used to host the conference.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="jitsi.riot.im"
|
placeholder="jitsi.riot.im"
|
||||||
[(ngModel)]="widget.options.jitsiDomain" [disabled]="isUpdating"/>
|
[(ngModel)]="widget.options.jitsiDomain" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Use this domain as the default conference domain' | translate}}
|
{{'Use this domain as the default conference domain' | translate}}
|
||||||
<span class="text-muted ">{{'Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you\'ll force Dimension to use your Jitsi domain at risk of having clients not respect it.' | translate}}</span>
|
<span class="text-muted ">{{'Some clients can create widgets that are not compatible with Dimension, making Dimension use jitsi.riot.im by default. By enabling this option, you\'ll force Dimension to use your Jitsi domain at risk of having clients not respect it.' | translate}}</span>
|
||||||
<ui-switch [checked]="widget.options.useDomainAsDefault" size="medium" [disabled]="isUpdating"
|
<ui-switch [checked]="widget.options.useDomainAsDefault" size="medium" [disabled]="isUpdating"
|
||||||
(change)="toggleForcedJitsi()"></ui-switch>
|
(change)="toggleForcedJitsi()"></ui-switch>
|
||||||
</label>
|
</label>
|
||||||
<label class="label-block">
|
<label class="label-block">
|
||||||
{{'Jitsi Script URL' | translate}}
|
{{'Jitsi Script URL' | translate}}
|
||||||
<span class="text-muted ">{{'This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.' | translate}}</span>
|
<span class="text-muted ">{{'This is used to create the Jitsi widget. It is normally at /libs/external_api.min.js from your domain.' | translate}}</span>
|
||||||
<input type="text" class="form-control"
|
<input type="text" class="form-control"
|
||||||
placeholder="https://jitsi.riot.im/libs/external_api.min.js"
|
placeholder="https://jitsi.riot.im/libs/external_api.min.js"
|
||||||
[(ngModel)]="widget.options.scriptUrl" [disabled]="isUpdating"/>
|
[(ngModel)]="widget.options.scriptUrl" [disabled]="isUpdating"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-save"></i> {{'Save' | translate}}
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,24 +1,29 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FE_JitsiWidget } from "../../../shared/models/integration";
|
import { FE_JitsiWidget } from "../../../shared/models/integration";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
|
||||||
import { WidgetConfigDialogContext } from "../widgets.component";
|
|
||||||
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./jitsi.component.html",
|
templateUrl: "./jitsi.component.html",
|
||||||
styleUrls: ["./jitsi.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./jitsi.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminWidgetJitsiConfigComponent implements ModalComponent<WidgetConfigDialogContext> {
|
export class AdminWidgetJitsiConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public widget: FE_JitsiWidget;
|
public widget: FE_JitsiWidget;
|
||||||
private originalWidget: FE_JitsiWidget;
|
private originalWidget = <FE_JitsiWidget>{};
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<WidgetConfigDialogContext>, private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, public translate: TranslateService) {
|
constructor(public modal: NgbActiveModal,
|
||||||
this.translate = translate;
|
private adminIntegrationsApi: AdminIntegrationsApiService,
|
||||||
this.originalWidget = dialog.context.widget;
|
private toaster: ToasterService,
|
||||||
|
public translate: TranslateService) {
|
||||||
|
this.translate = translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.originalWidget = this.widget;
|
||||||
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
||||||
|
|
||||||
// Fix the ui-switch not picking up a boolean value
|
// Fix the ui-switch not picking up a boolean value
|
||||||
@ -30,7 +35,7 @@ export class AdminWidgetJitsiConfigComponent implements ModalComponent<WidgetCon
|
|||||||
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
||||||
this.originalWidget.options = this.widget.options;
|
this.originalWidget.options = this.widget.options;
|
||||||
this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
this.translate.get('Widget updated').subscribe((res: string) => {this.toaster.pop("success", res); });
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -1,22 +1,20 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">Whiteboard Widget Configuration</h4>
|
||||||
<h4>Whiteboard Widget Configuration</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
|
||||||
<div class="dialog-content">
|
|
||||||
<label class="label-block">
|
|
||||||
Default Board URL Template
|
|
||||||
<span class="text-muted ">$boardName and $roomId will be replaced during creation to help create a unique pad URL.</span>
|
|
||||||
<input type="text" class="form-control"
|
|
||||||
placeholder="https://cloud13.de/testwhiteboard/?whiteboardid=$roomId_$boardName"
|
|
||||||
[(ngModel)]="widget.options.defaultUrl" [disabled]="isUpdating"/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-footer">
|
|
||||||
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
|
||||||
<i class="far fa-save"></i> Save
|
|
||||||
</button>
|
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
|
||||||
<i class="far fa-times-circle"></i> Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
Default Board URL Template
|
||||||
|
<span class="text-muted ">$boardName and $roomId will be replaced during creation to help create a unique pad URL.</span>
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
placeholder="https://cloud13.de/testwhiteboard/?whiteboardid=$roomId_$boardName"
|
||||||
|
[(ngModel)]="widget.options.defaultUrl" [disabled]="isUpdating"/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" (click)="save()" title="save" class="btn btn-primary btn-sm">
|
||||||
|
<i class="far fa-save"></i> {{'Save' | translate}}
|
||||||
|
</button>
|
||||||
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
|
<i class="far fa-times-circle"></i> {{'Cancel' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
@ -1,22 +1,29 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FE_WhiteBoardWidget } from "../../../shared/models/integration";
|
import { FE_WhiteBoardWidget } from "../../../shared/models/integration";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { WidgetConfigDialogContext } from "../widgets.component";
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
import { AdminIntegrationsApiService } from "../../../shared/services/admin/admin-integrations-api.service";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./whiteboard.component.html",
|
templateUrl: "./whiteboard.component.html",
|
||||||
styleUrls: ["./whiteboard.component.scss", "../config-dialog.scss"],
|
styleUrls: ["./whiteboard.component.scss", "../config-dialog.scss"],
|
||||||
})
|
})
|
||||||
export class AdminWidgetWhiteboardConfigComponent implements ModalComponent<WidgetConfigDialogContext> {
|
export class AdminWidgetWhiteboardConfigComponent implements OnInit {
|
||||||
|
|
||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public widget: FE_WhiteBoardWidget;
|
public widget: FE_WhiteBoardWidget;
|
||||||
private originalWidget: FE_WhiteBoardWidget;
|
private originalWidget: FE_WhiteBoardWidget;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<WidgetConfigDialogContext>, private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService) {
|
constructor(public modal: NgbActiveModal,
|
||||||
this.originalWidget = dialog.context.widget;
|
private adminIntegrationsApi: AdminIntegrationsApiService,
|
||||||
|
private toaster: ToasterService,
|
||||||
|
public translate: TranslateService) {
|
||||||
|
this.translate = translate;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.originalWidget = this.widget;
|
||||||
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
this.widget = JSON.parse(JSON.stringify(this.originalWidget));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +32,7 @@ export class AdminWidgetWhiteboardConfigComponent implements ModalComponent<Widg
|
|||||||
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
this.adminIntegrationsApi.setIntegrationOptions(this.widget.category, this.widget.type, this.widget.options).then(() => {
|
||||||
this.originalWidget.options = this.widget.options;
|
this.originalWidget.options = this.widget.options;
|
||||||
this.toaster.pop("success", "Widget updated");
|
this.toaster.pop("success", "Widget updated");
|
||||||
this.dialog.close();
|
this.modal.close();
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
console.error(err);
|
console.error(err);
|
||||||
|
@ -2,15 +2,14 @@ import { Component } from "@angular/core";
|
|||||||
import { FE_Widget } from "../../shared/models/integration";
|
import { FE_Widget } from "../../shared/models/integration";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { AdminWidgetEtherpadConfigComponent } from "./etherpad/etherpad.component";
|
import { AdminWidgetEtherpadConfigComponent } from "./etherpad/etherpad.component";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { AdminWidgetJitsiConfigComponent } from "./jitsi/jitsi.component";
|
import { AdminWidgetJitsiConfigComponent } from "./jitsi/jitsi.component";
|
||||||
import { AdminIntegrationsApiService } from "../../shared/services/admin/admin-integrations-api.service";
|
import { AdminIntegrationsApiService } from "../../shared/services/admin/admin-integrations-api.service";
|
||||||
import { AdminWidgetWhiteboardConfigComponent } from "./whiteboard/whiteboard.component";
|
import { AdminWidgetWhiteboardConfigComponent } from "./whiteboard/whiteboard.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
export class WidgetConfigDialogContext extends BSModalContext {
|
export interface WidgetConfigDialogContext {
|
||||||
public widget: FE_Widget;
|
widget: FE_Widget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -23,7 +22,7 @@ export class AdminWidgetsComponent {
|
|||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public widgets: FE_Widget[];
|
public widgets: FE_Widget[];
|
||||||
|
|
||||||
constructor(private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, private modal: Modal, public translate: TranslateService) {
|
constructor(private adminIntegrationsApi: AdminIntegrationsApiService, private toaster: ToasterService, private modal: NgbModal, public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.adminIntegrationsApi.getAllWidgets().then(widgets => {
|
this.adminIntegrationsApi.getAllWidgets().then(widgets => {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@ -61,12 +60,11 @@ export class AdminWidgetsComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modal.open(component, overlayConfigFactory({
|
const widgetConfigRef = this.modal.open(component, {
|
||||||
widget: widget,
|
backdrop: 'static'
|
||||||
|
});
|
||||||
isBlocking: true,
|
const widgetConfigInterface = widgetConfigRef.componentInstance as WidgetConfigDialogContext;
|
||||||
size: 'lg',
|
widgetConfigInterface.widget = widget;
|
||||||
}, WidgetConfigDialogContext));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasConfiguration(widget: FE_Widget) {
|
public hasConfiguration(widget: FE_Widget) {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { ApplicationRef, Injector, NgModule } from "@angular/core";
|
import { ApplicationRef, Injector, NgModule } from "@angular/core";
|
||||||
import { ModalModule } from "ngx-modialog";
|
|
||||||
import { BootstrapModalModule } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { BreadcrumbModule } from "xng-breadcrumb";
|
import { BreadcrumbModule } from "xng-breadcrumb";
|
||||||
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
import { UiSwitchModule } from "ngx-ui-switch";
|
import { UiSwitchModule } from "ngx-ui-switch";
|
||||||
@ -137,9 +135,7 @@ export function HttpLoaderFactory(http: HttpClient) {
|
|||||||
UiSwitchModule,
|
UiSwitchModule,
|
||||||
ToasterModule,
|
ToasterModule,
|
||||||
BrowserAnimationsModule,
|
BrowserAnimationsModule,
|
||||||
ModalModule.forRoot(),
|
BreadcrumbModule,
|
||||||
BootstrapModalModule,
|
|
||||||
BreadcrumbsModule,
|
|
||||||
CKEditorModule,
|
CKEditorModule,
|
||||||
FontAwesomeModule,
|
FontAwesomeModule,
|
||||||
TranslateModule.forRoot({
|
TranslateModule.forRoot({
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Telegram chat is already bridged' | translate}}</h4>
|
||||||
<h4>{{'Telegram chat is already bridged' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
{{'You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?' | translate}}
|
{{'You have the appropriate permissions to be able to unbridge the chat, however. Would you like to unbridge the other room and instead bridge it here?' | translate}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="unbridgeAndContinue()" title="unbridge and continue"
|
<button type="button" (click)="unbridgeAndContinue()" title="unbridge and continue" class="btn btn-danger btn-sm">
|
||||||
class="btn btn-danger btn-sm">
|
{{'Unbridge and continue' | translate}}
|
||||||
{{'Unbridge and continue' | translate}}
|
</button>
|
||||||
</button>
|
<button type="button" (click)="cancel()" title="cancel" class="btn btn-primary btn-sm">
|
||||||
<button type="button" (click)="cancel()" title="cancel" class="btn btn-primary btn-sm">
|
<i class="far fa-times-circle"></i> {{'No, don\'t bridge' | translate}}
|
||||||
<i class="far fa-times-circle"></i> {{'No, don\'t bridge' | translate}}
|
</button>
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,24 +1,23 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
|
|
||||||
export class AskUnbridgeDialogContext extends BSModalContext {
|
export interface AskUnbridgeDialogContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./ask-unbridge.component.html",
|
templateUrl: "./ask-unbridge.component.html",
|
||||||
styleUrls: ["./ask-unbridge.component.scss"],
|
styleUrls: ["./ask-unbridge.component.scss"],
|
||||||
})
|
})
|
||||||
export class TelegramAskUnbridgeComponent implements ModalComponent<AskUnbridgeDialogContext> {
|
export class TelegramAskUnbridgeComponent {
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<AskUnbridgeDialogContext>) {
|
constructor(public modal: NgbActiveModal) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public unbridgeAndContinue(): void {
|
public unbridgeAndContinue(): void {
|
||||||
this.dialog.close({unbridge: true});
|
this.modal.close({unbridge: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
public cancel(): void {
|
public cancel(): void {
|
||||||
this.dialog.close({unbridge: false});
|
this.modal.close({unbridge: false});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{'Telegram chat is already bridged' | translate}}</h4>
|
||||||
<h4>{{'Telegram chat is already bridged' | translate}}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content">
|
<div class="modal-body">
|
||||||
{{'That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.' | translate}}
|
{{'That Telegram chat is bridged to another Matrix room and cannot be bridged here. Unfortunately, you do not have the required permissions to be able to unbridge the other room.' | translate}}
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="dialog.close()" title="cancel" class="btn btn-primary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-primary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { DialogRef, ModalComponent } from "ngx-modialog";
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
|
|
||||||
export class CannotUnbridgeDialogContext extends BSModalContext {
|
export interface CannotUnbridgeDialogContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./cannot-unbridge.component.html",
|
templateUrl: "./cannot-unbridge.component.html",
|
||||||
styleUrls: ["./cannot-unbridge.component.scss"],
|
styleUrls: ["./cannot-unbridge.component.scss"],
|
||||||
})
|
})
|
||||||
export class TelegramCannotUnbridgeComponent implements ModalComponent<CannotUnbridgeDialogContext> {
|
export class TelegramCannotUnbridgeComponent {
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<CannotUnbridgeDialogContext>) {
|
constructor(public modal: NgbActiveModal) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,12 @@ import { Component } from "@angular/core";
|
|||||||
import { BridgeComponent } from "../bridge.component";
|
import { BridgeComponent } from "../bridge.component";
|
||||||
import { TelegramApiService } from "../../../shared/services/integrations/telegram-api.service";
|
import { TelegramApiService } from "../../../shared/services/integrations/telegram-api.service";
|
||||||
import { FE_PortalInfo } from "../../../shared/models/telegram";
|
import { FE_PortalInfo } from "../../../shared/models/telegram";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
import { TelegramAskUnbridgeComponent } from "./ask-unbridge/ask-unbridge.component";
|
||||||
import { AskUnbridgeDialogContext, TelegramAskUnbridgeComponent } from "./ask-unbridge/ask-unbridge.component";
|
|
||||||
import {
|
import {
|
||||||
CannotUnbridgeDialogContext,
|
|
||||||
TelegramCannotUnbridgeComponent
|
TelegramCannotUnbridgeComponent
|
||||||
} from "./cannot-unbridge/cannot-unbridge.component";
|
} from "./cannot-unbridge/cannot-unbridge.component";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
interface TelegramConfig {
|
interface TelegramConfig {
|
||||||
puppet: {
|
puppet: {
|
||||||
@ -40,7 +39,7 @@ export class TelegramBridgeConfigComponent extends BridgeComponent<TelegramConfi
|
|||||||
|
|
||||||
public isUpdating: boolean;
|
public isUpdating: boolean;
|
||||||
|
|
||||||
constructor(private telegram: TelegramApiService, private modal: Modal, public translate: TranslateService) {
|
constructor(private telegram: TelegramApiService, private modal: NgbModal, public translate: TranslateService) {
|
||||||
super("telegram", translate);
|
super("telegram", translate);
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
}
|
}
|
||||||
@ -80,21 +79,22 @@ export class TelegramBridgeConfigComponent extends BridgeComponent<TelegramConfi
|
|||||||
this.telegram.getPortalInfo(this.bridge.config.portalInfo.chatId, this.roomId).then(async (chatInfo) => {
|
this.telegram.getPortalInfo(this.bridge.config.portalInfo.chatId, this.roomId).then(async (chatInfo) => {
|
||||||
let forceUnbridge = false;
|
let forceUnbridge = false;
|
||||||
if (chatInfo.bridged && chatInfo.canUnbridge) {
|
if (chatInfo.bridged && chatInfo.canUnbridge) {
|
||||||
const response = await this.modal.open(TelegramAskUnbridgeComponent, overlayConfigFactory({
|
const askUnbridgeRef = this.modal.open(TelegramAskUnbridgeComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, AskUnbridgeDialogContext)).result;
|
});
|
||||||
|
askUnbridgeRef.result.then((response) => {
|
||||||
if (response.unbridge) {
|
if (response.unbridge) {
|
||||||
forceUnbridge = true;
|
forceUnbridge = true;
|
||||||
} else {
|
} else {
|
||||||
return {aborted: true};
|
return {aborted: true};
|
||||||
}
|
}
|
||||||
|
});
|
||||||
} else if (chatInfo.bridged) {
|
} else if (chatInfo.bridged) {
|
||||||
this.modal.open(TelegramCannotUnbridgeComponent, overlayConfigFactory({
|
this.modal.open(TelegramCannotUnbridgeComponent, {
|
||||||
isBlocking: true,
|
backdrop: 'static',
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
}, CannotUnbridgeDialogContext));
|
});
|
||||||
return {aborted: true};
|
return {aborted: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
<div class="dialog">
|
<div class="modal-header">
|
||||||
<div class="dialog-header">
|
<h4 class="modal-title" id="modal-basic-title">{{ bot.displayName }}</h4>
|
||||||
<h4>{{ bot.displayName }}</h4>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" (click)="modal.close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-content" style="text-align: center;">
|
<div class="modal-body">
|
||||||
<p>{{ bot.description }}</p>
|
<p>{{ bot.description }}</p>
|
||||||
<ui-switch [checked]="bot._inRoom" [disabled]="bot._isUpdating" (change)="toggle()"></ui-switch>
|
<ui-switch [checked]="bot._inRoom" [disabled]="bot._isUpdating" (change)="toggle()"></ui-switch>
|
||||||
</div>
|
</div>
|
||||||
<div class="dialog-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" (click)="dialog.close()" title="close" class="btn btn-secondary btn-sm">
|
<button type="button" (click)="modal.close()" title="close" class="btn btn-secondary btn-sm">
|
||||||
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
<i class="far fa-times-circle"></i> {{'Close' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,36 +1,35 @@
|
|||||||
import { Component } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { FE_SimpleBot } from "../../shared/models/integration";
|
import { FE_SimpleBot } from "../../shared/models/integration";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service";
|
import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service";
|
||||||
import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service";
|
import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service";
|
||||||
import { BSModalContext } from "ngx-modialog/plugins/bootstrap";
|
|
||||||
import { DialogRef } from "ngx-modialog";
|
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbActiveModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
export class SimpleBotConfigDialogContext extends BSModalContext {
|
export interface SimpleBotConfigDialogContext {
|
||||||
public bot: FE_SimpleBot;
|
bot: FE_SimpleBot;
|
||||||
public roomId: string;
|
roomId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "simple-bot.component.html",
|
templateUrl: "simple-bot.component.html",
|
||||||
styleUrls: ["simple-bot.component.scss"],
|
styleUrls: ["simple-bot.component.scss"],
|
||||||
})
|
})
|
||||||
export class ConfigSimpleBotComponent {
|
export class ConfigSimpleBotComponent implements OnInit {
|
||||||
|
|
||||||
public bot: FE_SimpleBot;
|
public bot: FE_SimpleBot;
|
||||||
|
|
||||||
private roomId: string;
|
private roomId: string;
|
||||||
|
|
||||||
constructor(public dialog: DialogRef<SimpleBotConfigDialogContext>,
|
constructor(public modal: NgbActiveModal,
|
||||||
private toaster: ToasterService,
|
private toaster: ToasterService,
|
||||||
private scalar: ScalarClientApiService,
|
private scalar: ScalarClientApiService,
|
||||||
private integrationsApi: IntegrationsApiService,
|
private integrationsApi: IntegrationsApiService,
|
||||||
public translate: TranslateService) {
|
public translate: TranslateService) {
|
||||||
this.translate = translate;
|
this.translate = translate;
|
||||||
this.bot = dialog.context.bot;
|
}
|
||||||
this.roomId = dialog.context.roomId;
|
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
this.bot._isUpdating = false;
|
this.bot._isUpdating = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,322 +3,481 @@ import { ActivatedRoute, Router } from "@angular/router";
|
|||||||
import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service";
|
import { ScalarClientApiService } from "../../shared/services/scalar/scalar-client-api.service";
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import { ScalarServerApiService } from "../../shared/services/scalar/scalar-server-api.service";
|
import { ScalarServerApiService } from "../../shared/services/scalar/scalar-server-api.service";
|
||||||
import { FE_Integration, FE_IntegrationRequirement, FE_SimpleBot } from "../../shared/models/integration";
|
import {
|
||||||
|
FE_Integration,
|
||||||
|
FE_IntegrationRequirement,
|
||||||
|
FE_SimpleBot,
|
||||||
|
} from "../../shared/models/integration";
|
||||||
import { IntegrationsRegistry } from "../../shared/registry/integrations.registry";
|
import { IntegrationsRegistry } from "../../shared/registry/integrations.registry";
|
||||||
import { SessionStorage } from "../../shared/SessionStorage";
|
import { SessionStorage } from "../../shared/SessionStorage";
|
||||||
import { AdminApiService } from "../../shared/services/admin/admin-api.service";
|
import { AdminApiService } from "../../shared/services/admin/admin-api.service";
|
||||||
import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service";
|
import { IntegrationsApiService } from "../../shared/services/integrations/integrations-api.service";
|
||||||
import { Modal, overlayConfigFactory } from "ngx-modialog";
|
import {
|
||||||
import { ConfigSimpleBotComponent, SimpleBotConfigDialogContext } from "../../configs/simple-bot/simple-bot.component";
|
ConfigSimpleBotComponent,
|
||||||
|
SimpleBotConfigDialogContext,
|
||||||
|
} from "../../configs/simple-bot/simple-bot.component";
|
||||||
import { ToasterService } from "angular2-toaster";
|
import { ToasterService } from "angular2-toaster";
|
||||||
import { StickerApiService } from "../../shared/services/integrations/sticker-api.service";
|
import { StickerApiService } from "../../shared/services/integrations/sticker-api.service";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
const CATEGORY_MAP = {
|
const CATEGORY_MAP = {
|
||||||
"Widgets": ["widget"],
|
Widgets: ["widget"],
|
||||||
"Bots": ["complex-bot", "bot"],
|
Bots: ["complex-bot", "bot"],
|
||||||
"Bridges": ["bridge"],
|
Bridges: ["bridge"],
|
||||||
};
|
};
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "my-riot-home",
|
selector: "my-riot-home",
|
||||||
templateUrl: "./home.component.html",
|
templateUrl: "./home.component.html",
|
||||||
styleUrls: ["./home.component.scss"],
|
styleUrls: ["./home.component.scss"],
|
||||||
})
|
})
|
||||||
export class RiotHomeComponent {
|
export class RiotHomeComponent {
|
||||||
public isLoading = true;
|
public isLoading = true;
|
||||||
public isError = false;
|
public isError = false;
|
||||||
public errorMessage: string;
|
public errorMessage: string;
|
||||||
public isRoomEncrypted: boolean;
|
public isRoomEncrypted: boolean;
|
||||||
public hasStickerPacks = false;
|
public hasStickerPacks = false;
|
||||||
|
|
||||||
private roomId: string;
|
private roomId: string;
|
||||||
private userId: string;
|
private userId: string;
|
||||||
private requestedScreen: string = null;
|
private requestedScreen: string = null;
|
||||||
private requestedIntegrationId: string = null;
|
private requestedIntegrationId: string = null;
|
||||||
public integrationsForCategory: { [category: string]: FE_Integration[] } = {};
|
public integrationsForCategory: { [category: string]: FE_Integration[] } = {};
|
||||||
private categoryMap: { [categoryName: string]: string[] } = CATEGORY_MAP;
|
private categoryMap: { [categoryName: string]: string[] } = CATEGORY_MAP;
|
||||||
|
|
||||||
constructor(private activatedRoute: ActivatedRoute,
|
constructor(
|
||||||
private scalarApi: ScalarServerApiService,
|
private activatedRoute: ActivatedRoute,
|
||||||
private scalar: ScalarClientApiService,
|
private scalarApi: ScalarServerApiService,
|
||||||
private integrationsApi: IntegrationsApiService,
|
private scalar: ScalarClientApiService,
|
||||||
private stickerApi: StickerApiService,
|
private integrationsApi: IntegrationsApiService,
|
||||||
private adminApi: AdminApiService,
|
private stickerApi: StickerApiService,
|
||||||
private router: Router,
|
private adminApi: AdminApiService,
|
||||||
private modal: Modal,
|
private router: Router,
|
||||||
private toaster: ToasterService,
|
private modal: NgbModal,
|
||||||
public translate: TranslateService) {
|
private toaster: ToasterService,
|
||||||
this.translate = translate;
|
public translate: TranslateService
|
||||||
let params: any = this.activatedRoute.snapshot.queryParams;
|
) {
|
||||||
|
this.translate = translate;
|
||||||
|
let params: any = this.activatedRoute.snapshot.queryParams;
|
||||||
|
|
||||||
this.requestedScreen = params.screen;
|
this.requestedScreen = params.screen;
|
||||||
this.requestedIntegrationId = params.integ_id;
|
this.requestedIntegrationId = params.integ_id;
|
||||||
|
|
||||||
if (SessionStorage.roomId && SessionStorage.userId) {
|
if (SessionStorage.roomId && SessionStorage.userId) {
|
||||||
this.roomId = SessionStorage.roomId;
|
this.roomId = SessionStorage.roomId;
|
||||||
this.userId = SessionStorage.userId;
|
this.userId = SessionStorage.userId;
|
||||||
console.log("Already checked scalar token and other params - continuing startup");
|
console.log(
|
||||||
|
"Already checked scalar token and other params - continuing startup"
|
||||||
|
);
|
||||||
|
this.prepareIntegrations();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!params.scalar_token || !params.room_id) {
|
||||||
|
console.error(
|
||||||
|
"Unable to load Dimension. Missing room ID or scalar token."
|
||||||
|
);
|
||||||
|
this.isError = true;
|
||||||
|
this.isLoading = false;
|
||||||
|
this.translate
|
||||||
|
.get("Unable to load Dimension - missing room ID or token.")
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
this.errorMessage = res;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.roomId = params.room_id;
|
||||||
|
SessionStorage.scalarToken = params.scalar_token;
|
||||||
|
SessionStorage.roomId = this.roomId;
|
||||||
|
|
||||||
|
this.scalarApi
|
||||||
|
.getAccount()
|
||||||
|
.then((response) => {
|
||||||
|
const userId = response.user_id;
|
||||||
|
SessionStorage.userId = userId;
|
||||||
|
if (!userId) {
|
||||||
|
console.error(
|
||||||
|
"No user returned for token. Is the token registered in Dimension?"
|
||||||
|
);
|
||||||
|
this.isError = true;
|
||||||
|
this.isLoading = false;
|
||||||
|
this.translate
|
||||||
|
.get(
|
||||||
|
"Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!"
|
||||||
|
)
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
this.errorMessage = res;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.userId = userId;
|
||||||
|
console.log("Scalar token belongs to " + userId);
|
||||||
|
this.checkAdmin();
|
||||||
this.prepareIntegrations();
|
this.prepareIntegrations();
|
||||||
return;
|
}
|
||||||
}
|
})
|
||||||
|
.catch((err) => {
|
||||||
if (!params.scalar_token || !params.room_id) {
|
console.error(err);
|
||||||
console.error("Unable to load Dimension. Missing room ID or scalar token.");
|
this.isError = true;
|
||||||
this.isError = true;
|
this.isLoading = false;
|
||||||
this.isLoading = false;
|
this.translate
|
||||||
this.translate.get('Unable to load Dimension - missing room ID or token.').subscribe((res: string) => {this.errorMessage = res});
|
.get(
|
||||||
} else {
|
"Unable to communicate with Dimension due to an unknown error."
|
||||||
this.roomId = params.room_id;
|
)
|
||||||
SessionStorage.scalarToken = params.scalar_token;
|
.subscribe((res: string) => {
|
||||||
SessionStorage.roomId = this.roomId;
|
this.errorMessage = res;
|
||||||
|
|
||||||
this.scalarApi.getAccount().then(response => {
|
|
||||||
const userId = response.user_id;
|
|
||||||
SessionStorage.userId = userId;
|
|
||||||
if (!userId) {
|
|
||||||
console.error("No user returned for token. Is the token registered in Dimension?");
|
|
||||||
this.isError = true;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.translate.get('Could not verify your token. Please try logging out of Element and back in. Be sure to back up your encryption keys!').subscribe((res: string) => {this.errorMessage = res});
|
|
||||||
} else {
|
|
||||||
this.userId = userId;
|
|
||||||
console.log("Scalar token belongs to " + userId);
|
|
||||||
this.checkAdmin();
|
|
||||||
this.prepareIntegrations();
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
this.isError = true;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.translate.get('Unable to communicate with Dimension due to an unknown error.').subscribe((res: string) => {this.errorMessage = res});
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkAdmin() {
|
||||||
|
this.adminApi
|
||||||
|
.isAdmin()
|
||||||
|
.then(() => {
|
||||||
|
console.log(
|
||||||
|
SessionStorage.userId + " is an admin for this Dimension instance"
|
||||||
|
);
|
||||||
|
SessionStorage.isAdmin = true;
|
||||||
|
})
|
||||||
|
.catch(() => (SessionStorage.isAdmin = false));
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasIntegrations(): boolean {
|
||||||
|
for (const category of this.getCategories()) {
|
||||||
|
if (this.getIntegrationsIn(category).length > 0) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkAdmin() {
|
return false;
|
||||||
this.adminApi.isAdmin().then(() => {
|
}
|
||||||
console.log(SessionStorage.userId + " is an admin for this Dimension instance");
|
|
||||||
SessionStorage.isAdmin = true;
|
public getCategories(): string[] {
|
||||||
}).catch(() => SessionStorage.isAdmin = false);
|
return Object.keys(this.categoryMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIntegrationsIn(category: string): FE_Integration[] {
|
||||||
|
return this.integrationsForCategory[category];
|
||||||
|
}
|
||||||
|
|
||||||
|
private getIntegrations(): FE_Integration[] {
|
||||||
|
const result: FE_Integration[] = [];
|
||||||
|
|
||||||
|
for (const category of this.getCategories()) {
|
||||||
|
for (const integration of this.getIntegrationsIn(category)) {
|
||||||
|
result.push(integration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public hasIntegrations(): boolean {
|
return result;
|
||||||
for (const category of this.getCategories()) {
|
}
|
||||||
if (this.getIntegrationsIn(category).length > 0) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
public modifyIntegration(integration: FE_Integration) {
|
||||||
|
if (!integration._isSupported) {
|
||||||
|
console.log(
|
||||||
|
this.userId +
|
||||||
|
" tried to modify " +
|
||||||
|
integration.displayName +
|
||||||
|
" with error: " +
|
||||||
|
integration._notSupportedReason
|
||||||
|
);
|
||||||
|
this.translate
|
||||||
|
.get(
|
||||||
|
"You do not appear to have permission to modify widgets in this room"
|
||||||
|
)
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
const reason =
|
||||||
|
integration.category === "widget"
|
||||||
|
? res
|
||||||
|
: integration._notSupportedReason;
|
||||||
|
this.toaster.pop("error", reason);
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCategories(): string[] {
|
SessionStorage.editIntegration = integration;
|
||||||
return Object.keys(this.categoryMap);
|
SessionStorage.editsRequested++;
|
||||||
|
console.log(
|
||||||
|
this.userId + " is trying to modify " + integration.displayName
|
||||||
|
);
|
||||||
|
|
||||||
|
if (integration.category === "bot") {
|
||||||
|
const widgetConfigRef = this.modal.open(ConfigSimpleBotComponent, {
|
||||||
|
backdrop: "static",
|
||||||
|
size: "lg",
|
||||||
|
});
|
||||||
|
const widgetConfigInterface =
|
||||||
|
widgetConfigRef.componentInstance as SimpleBotConfigDialogContext;
|
||||||
|
widgetConfigInterface.bot = <FE_SimpleBot>integration;
|
||||||
|
widgetConfigInterface.roomId = this.roomId;
|
||||||
|
} else {
|
||||||
|
console.log(
|
||||||
|
"Navigating to edit screen for " +
|
||||||
|
integration.category +
|
||||||
|
" " +
|
||||||
|
integration.type
|
||||||
|
);
|
||||||
|
this.router.navigate(
|
||||||
|
["riot-app", integration.category, integration.type],
|
||||||
|
{ queryParams: { roomId: this.roomId } }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public getIntegrationsIn(category: string): FE_Integration[] {
|
private prepareIntegrations() {
|
||||||
return this.integrationsForCategory[category];
|
this.scalar
|
||||||
}
|
.isRoomEncrypted(this.roomId)
|
||||||
|
.then((payload) => {
|
||||||
|
this.isRoomEncrypted = payload.response;
|
||||||
|
return this.integrationsApi.getIntegrations(this.roomId);
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
const integrations: FE_Integration[] = _.flatten(
|
||||||
|
Object.keys(response).map((k) => response[k])
|
||||||
|
);
|
||||||
|
const supportedIntegrations: FE_Integration[] = _.filter(
|
||||||
|
integrations,
|
||||||
|
(i) => IntegrationsRegistry.isSupported(i)
|
||||||
|
);
|
||||||
|
|
||||||
private getIntegrations(): FE_Integration[] {
|
// Flag integrations that aren't supported in encrypted rooms
|
||||||
const result: FE_Integration[] = [];
|
if (this.isRoomEncrypted) {
|
||||||
|
for (const integration of supportedIntegrations) {
|
||||||
for (const category of this.getCategories()) {
|
if (!integration.isEncryptionSupported) {
|
||||||
for (const integration of this.getIntegrationsIn(category)) {
|
integration._isSupported = false;
|
||||||
result.push(integration);
|
integration._notSupportedReason =
|
||||||
|
"This integration is not supported in encrypted rooms";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
// Set up the categories
|
||||||
|
for (const category of Object.keys(this.categoryMap)) {
|
||||||
|
const supportedTypes = this.categoryMap[category];
|
||||||
|
this.integrationsForCategory[category] = _.filter(
|
||||||
|
supportedIntegrations,
|
||||||
|
(i) => supportedTypes.indexOf(i.category) !== -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let promises = supportedIntegrations.map((i) =>
|
||||||
|
this.updateIntegrationState(i)
|
||||||
|
);
|
||||||
|
return Promise.all(promises);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.isLoading = false;
|
||||||
|
|
||||||
|
// HACK: We wait for the digest cycle so we actually have components to look at
|
||||||
|
setTimeout(() => this.tryOpenConfigScreen(), 20);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
this.isError = true;
|
||||||
|
this.isLoading = false;
|
||||||
|
this.translate
|
||||||
|
.get(
|
||||||
|
"Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server."
|
||||||
|
)
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
this.errorMessage = res;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.stickerApi
|
||||||
|
.getPacks()
|
||||||
|
.then((packs) => {
|
||||||
|
this.hasStickerPacks = packs.length > 0;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private tryOpenConfigScreen() {
|
||||||
|
let category = null;
|
||||||
|
let type = null;
|
||||||
|
if (!this.requestedScreen) return;
|
||||||
|
|
||||||
|
if (this.requestedScreen === "type_m.stickerpicker") {
|
||||||
|
console.log(
|
||||||
|
"Intercepting config screen handling to open sticker picker config"
|
||||||
|
);
|
||||||
|
this.router.navigate(["riot-app", "stickerpicker"]);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public modifyIntegration(integration: FE_Integration) {
|
const targetIntegration = IntegrationsRegistry.getIntegrationForScreen(
|
||||||
if (!integration._isSupported) {
|
this.requestedScreen
|
||||||
console.log(this.userId + " tried to modify " + integration.displayName + " with error: " + integration._notSupportedReason);
|
);
|
||||||
this.translate.get('You do not appear to have permission to modify widgets in this room').subscribe((res: string) => {
|
if (targetIntegration) {
|
||||||
const reason = integration.category === "widget" ? res : integration._notSupportedReason;
|
category = targetIntegration.category;
|
||||||
this.toaster.pop("error", reason);
|
type = targetIntegration.type;
|
||||||
});
|
} else {
|
||||||
return;
|
console.log("Unknown screen requested: " + this.requestedScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("Searching for integration for requested screen");
|
||||||
|
for (const integration of this.getIntegrations()) {
|
||||||
|
if (integration.category === category && integration.type === type) {
|
||||||
|
console.log(
|
||||||
|
"Configuring integration " +
|
||||||
|
this.requestedIntegrationId +
|
||||||
|
" category=" +
|
||||||
|
category +
|
||||||
|
" type=" +
|
||||||
|
type
|
||||||
|
);
|
||||||
SessionStorage.editIntegration = integration;
|
SessionStorage.editIntegration = integration;
|
||||||
SessionStorage.editsRequested++;
|
SessionStorage.editIntegrationId = this.requestedIntegrationId;
|
||||||
console.log(this.userId + " is trying to modify " + integration.displayName);
|
this.modifyIntegration(integration);
|
||||||
|
return;
|
||||||
if (integration.category === "bot") {
|
}
|
||||||
this.modal.open(ConfigSimpleBotComponent, overlayConfigFactory({
|
|
||||||
bot: <FE_SimpleBot>integration,
|
|
||||||
roomId: this.roomId,
|
|
||||||
|
|
||||||
isBlocking: true,
|
|
||||||
size: 'lg',
|
|
||||||
}, SimpleBotConfigDialogContext));
|
|
||||||
} else {
|
|
||||||
console.log("Navigating to edit screen for " + integration.category + " " + integration.type);
|
|
||||||
this.router.navigate(['riot-app', integration.category, integration.type], {queryParams: {roomId: this.roomId}});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private prepareIntegrations() {
|
console.log(
|
||||||
this.scalar.isRoomEncrypted(this.roomId).then(payload => {
|
"Failed to find integration component for category=" +
|
||||||
this.isRoomEncrypted = payload.response;
|
category +
|
||||||
return this.integrationsApi.getIntegrations(this.roomId);
|
" type=" +
|
||||||
}).then(response => {
|
type
|
||||||
const integrations: FE_Integration[] = _.flatten(Object.keys(response).map(k => response[k]));
|
);
|
||||||
const supportedIntegrations: FE_Integration[] = _.filter(integrations, i => IntegrationsRegistry.isSupported(i));
|
}
|
||||||
|
|
||||||
// Flag integrations that aren't supported in encrypted rooms
|
private async updateIntegrationState(integration: FE_Integration) {
|
||||||
if (this.isRoomEncrypted) {
|
if (!integration.isOnline) {
|
||||||
for (const integration of supportedIntegrations) {
|
integration._isSupported = false;
|
||||||
if (!integration.isEncryptionSupported) {
|
this.translate
|
||||||
integration._isSupported = false;
|
.get("This integration is offline or unavailable")
|
||||||
integration._notSupportedReason = "This integration is not supported in encrypted rooms";
|
.subscribe((res: string) => {
|
||||||
}
|
integration._notSupportedReason = res;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set up the categories
|
|
||||||
for (const category of Object.keys(this.categoryMap)) {
|
|
||||||
const supportedTypes = this.categoryMap[category];
|
|
||||||
this.integrationsForCategory[category] = _.filter(supportedIntegrations, i => supportedTypes.indexOf(i.category) !== -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let promises = supportedIntegrations.map(i => this.updateIntegrationState(i));
|
|
||||||
return Promise.all(promises);
|
|
||||||
}).then(() => {
|
|
||||||
this.isLoading = false;
|
|
||||||
|
|
||||||
// HACK: We wait for the digest cycle so we actually have components to look at
|
|
||||||
setTimeout(() => this.tryOpenConfigScreen(), 20);
|
|
||||||
}).catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
this.isError = true;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.translate.get('Unable to set up Dimension. This version of Element may not supported or there may be a problem with the server.').subscribe((res: string) => {this.errorMessage = res});
|
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.stickerApi.getPacks().then(packs => {
|
if (!integration.requirements) return;
|
||||||
this.hasStickerPacks = packs.length > 0;
|
|
||||||
}).catch(err => {
|
let promises = integration.requirements.map((r) =>
|
||||||
console.error(err);
|
this.checkRequirement(r)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (integration.category === "bot") {
|
||||||
|
const state = await this.scalar.getMembershipState(
|
||||||
|
this.roomId,
|
||||||
|
(<FE_SimpleBot>integration).userId
|
||||||
|
);
|
||||||
|
if (state && state.response && state.response.membership) {
|
||||||
|
integration._inRoom =
|
||||||
|
["join", "invite"].indexOf(state.response.membership) !== -1;
|
||||||
|
} else integration._inRoom = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(promises).then(
|
||||||
|
() => {
|
||||||
|
integration._isSupported = true;
|
||||||
|
integration._notSupportedReason = null;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error(error);
|
||||||
|
integration._isSupported = false;
|
||||||
|
integration._notSupportedReason = error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkRequirement(requirement: FE_IntegrationRequirement) {
|
||||||
|
switch (requirement.condition) {
|
||||||
|
case "publicRoom":
|
||||||
|
return this.scalar.getJoinRule(this.roomId).then((payload) => {
|
||||||
|
if (!payload.response) {
|
||||||
|
let message: string;
|
||||||
|
this.translate
|
||||||
|
.get("Could not communicate with Element")
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
message = res;
|
||||||
|
});
|
||||||
|
return Promise.reject(message);
|
||||||
|
}
|
||||||
|
const isPublic = payload.response.join_rule === "public";
|
||||||
|
if (isPublic !== requirement.expectedValue) {
|
||||||
|
let message: string;
|
||||||
|
let message1: string;
|
||||||
|
this.translate
|
||||||
|
.get(["The room must be", "to use this integration"])
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
message = res[0];
|
||||||
|
message1 = res[1];
|
||||||
|
});
|
||||||
|
return Promise.reject(
|
||||||
|
message + (isPublic ? "non-public" : "public") + message1
|
||||||
|
);
|
||||||
|
} else return Promise.resolve();
|
||||||
});
|
});
|
||||||
}
|
case "canSendEventTypes":
|
||||||
|
const processPayload = (payload) => {
|
||||||
|
const response = <any>payload.response;
|
||||||
|
if (response === true) return Promise.resolve();
|
||||||
|
if (response.error || response.error.message) {
|
||||||
|
let message: string;
|
||||||
|
this.translate
|
||||||
|
.get("You cannot modify widgets in this room")
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
message = res;
|
||||||
|
});
|
||||||
|
return Promise.reject(message);
|
||||||
|
}
|
||||||
|
let message: string;
|
||||||
|
this.translate
|
||||||
|
.get("Error communicating with Element")
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
message = res;
|
||||||
|
});
|
||||||
|
return Promise.reject(message);
|
||||||
|
};
|
||||||
|
|
||||||
private tryOpenConfigScreen() {
|
let promiseChain = Promise.resolve();
|
||||||
let category = null;
|
requirement.argument.forEach(
|
||||||
let type = null;
|
(e) =>
|
||||||
if (!this.requestedScreen) return;
|
(promiseChain = promiseChain.then(() =>
|
||||||
|
this.scalar
|
||||||
if (this.requestedScreen === "type_m.stickerpicker") {
|
.canSendEvent(this.roomId, e.type, e.isState)
|
||||||
console.log("Intercepting config screen handling to open sticker picker config");
|
.then(processPayload)
|
||||||
this.router.navigate(['riot-app', 'stickerpicker']);
|
.catch(processPayload)
|
||||||
return;
|
))
|
||||||
}
|
);
|
||||||
|
return promiseChain
|
||||||
const targetIntegration = IntegrationsRegistry.getIntegrationForScreen(this.requestedScreen);
|
.then(() => {
|
||||||
if (targetIntegration) {
|
if (!requirement.expectedValue) {
|
||||||
category = targetIntegration.category;
|
let message: string;
|
||||||
type = targetIntegration.type;
|
this.translate
|
||||||
} else {
|
.get("Expected to not be able to send specific event types")
|
||||||
console.log("Unknown screen requested: " + this.requestedScreen);
|
.subscribe((res: string) => {
|
||||||
}
|
message = res;
|
||||||
|
|
||||||
console.log("Searching for integration for requested screen");
|
|
||||||
for (const integration of this.getIntegrations()) {
|
|
||||||
if (integration.category === category && integration.type === type) {
|
|
||||||
console.log("Configuring integration " + this.requestedIntegrationId + " category=" + category + " type=" + type);
|
|
||||||
SessionStorage.editIntegration = integration;
|
|
||||||
SessionStorage.editIntegrationId = this.requestedIntegrationId;
|
|
||||||
this.modifyIntegration(integration);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Failed to find integration component for category=" + category + " type=" + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async updateIntegrationState(integration: FE_Integration) {
|
|
||||||
if (!integration.isOnline) {
|
|
||||||
integration._isSupported = false;
|
|
||||||
this.translate.get('This integration is offline or unavailable').subscribe((res: string) => {integration._notSupportedReason = res});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!integration.requirements) return;
|
|
||||||
|
|
||||||
let promises = integration.requirements.map(r => this.checkRequirement(r));
|
|
||||||
|
|
||||||
if (integration.category === "bot") {
|
|
||||||
const state = await this.scalar.getMembershipState(this.roomId, (<FE_SimpleBot>integration).userId);
|
|
||||||
if (state && state.response && state.response.membership) {
|
|
||||||
integration._inRoom = ["join", "invite"].indexOf(state.response.membership) !== -1;
|
|
||||||
} else integration._inRoom = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.all(promises).then(() => {
|
|
||||||
integration._isSupported = true;
|
|
||||||
integration._notSupportedReason = null;
|
|
||||||
}, error => {
|
|
||||||
console.error(error);
|
|
||||||
integration._isSupported = false;
|
|
||||||
integration._notSupportedReason = error;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private checkRequirement(requirement: FE_IntegrationRequirement) {
|
|
||||||
switch (requirement.condition) {
|
|
||||||
case "publicRoom":
|
|
||||||
return this.scalar.getJoinRule(this.roomId).then(payload => {
|
|
||||||
if (!payload.response) {
|
|
||||||
let message: string;
|
|
||||||
this.translate.get('Could not communicate with Element').subscribe((res: string) => {message = res});
|
|
||||||
return Promise.reject(message);
|
|
||||||
}
|
|
||||||
const isPublic = payload.response.join_rule === "public";
|
|
||||||
if (isPublic !== requirement.expectedValue) {
|
|
||||||
let message: string;
|
|
||||||
let message1: string;
|
|
||||||
this.translate.get(['The room must be', 'to use this integration']).subscribe((res: string) => {message = res[0]; message1 = res[1]});
|
|
||||||
return Promise.reject(message + (isPublic ? "non-public" : "public") + message1);
|
|
||||||
} else return Promise.resolve();
|
|
||||||
});
|
});
|
||||||
case "canSendEventTypes":
|
return Promise.reject(message);
|
||||||
const processPayload = payload => {
|
}
|
||||||
const response = <any>payload.response;
|
})
|
||||||
if (response === true) return Promise.resolve();
|
.catch((err) => {
|
||||||
if (response.error || response.error.message) {
|
console.error(err);
|
||||||
let message: string;
|
if (requirement.expectedValue) {
|
||||||
this.translate.get('You cannot modify widgets in this room').subscribe((res: string) => {message = res});
|
let message: string;
|
||||||
return Promise.reject(message);
|
this.translate
|
||||||
}
|
.get("Expected to be able to send specific event types")
|
||||||
let message: string;
|
.subscribe((res: string) => {
|
||||||
this.translate.get('Error communicating with Element').subscribe((res: string) => {message = res});
|
message = res;
|
||||||
return Promise.reject(message);
|
|
||||||
};
|
|
||||||
|
|
||||||
let promiseChain = Promise.resolve();
|
|
||||||
requirement.argument.forEach(e => promiseChain = promiseChain.then(() => this.scalar.canSendEvent(this.roomId, e.type, e.isState).then(processPayload).catch(processPayload)));
|
|
||||||
return promiseChain.then(() => {
|
|
||||||
if (!requirement.expectedValue) {
|
|
||||||
let message: string;
|
|
||||||
this.translate.get('Expected to not be able to send specific event types').subscribe((res: string) => {message = res});
|
|
||||||
return Promise.reject(message);
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
if (requirement.expectedValue) {
|
|
||||||
let message: string;
|
|
||||||
this.translate.get('Expected to be able to send specific event types').subscribe((res: string) => {message = res});
|
|
||||||
return Promise.reject(message);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
case "userInRoom":
|
return Promise.reject(message);
|
||||||
// TODO: Implement
|
}
|
||||||
default:
|
});
|
||||||
let message: string;
|
case "userInRoom":
|
||||||
let message1: string;
|
// TODO: Implement
|
||||||
this.translate.get(['Requirement', 'not found']).subscribe((res: string) => {message = res[0]; message1 = res[1]});
|
default:
|
||||||
return Promise.reject(message + requirement.condition + message1);
|
let message: string;
|
||||||
}
|
let message1: string;
|
||||||
|
this.translate
|
||||||
|
.get(["Requirement", "not found"])
|
||||||
|
.subscribe((res: string) => {
|
||||||
|
message = res[0];
|
||||||
|
message1 = res[1];
|
||||||
|
});
|
||||||
|
return Promise.reject(message + requirement.condition + message1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// styles in src/style directory are applied to the whole page
|
// styles in src/style directory are applied to the whole page
|
||||||
@import "../assets//fonts/opensans100-roboto300";
|
@import "../assets//fonts/opensans100-roboto300";
|
||||||
@import "../../node_modules/angular2-toaster/toaster";
|
@import "../../node_modules/angular2-toaster/toaster";
|
||||||
@import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
|
@import "~bootstrap/scss/bootstrap";
|
||||||
@import "~ngx-ui-switch/ui-switch.component.scss";
|
@import "~ngx-ui-switch/ui-switch.component.scss";
|
||||||
@import "themes/themes";
|
@import "themes/themes";
|
||||||
@import "components/ibox";
|
@import "components/ibox";
|
||||||
|
Loading…
Reference in New Issue
Block a user