mirror of
https://github.com/turt2live/matrix-dimension.git
synced 2024-10-01 01:05:53 -04:00
Custom widget edit screen
This commit is contained in:
parent
6740571183
commit
dd02c6df2c
@ -32,6 +32,7 @@ import { DimensionApiService } from "./shared/services/dimension-api.service";
|
|||||||
import { AdminApiService } from "./shared/services/admin-api.service";
|
import { AdminApiService } from "./shared/services/admin-api.service";
|
||||||
import { ServiceLocator } from "./shared/services/locator.service";
|
import { ServiceLocator } from "./shared/services/locator.service";
|
||||||
import { IboxComponent } from "./elements/ibox/ibox.component";
|
import { IboxComponent } from "./elements/ibox/ibox.component";
|
||||||
|
import { CustomWidgetConfigComponent } from "./configs/widget/custom/custom.widget.component";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -64,6 +65,7 @@ import { IboxComponent } from "./elements/ibox/ibox.component";
|
|||||||
GCalWidgetWrapperComponent,
|
GCalWidgetWrapperComponent,
|
||||||
RiotHomeComponent,
|
RiotHomeComponent,
|
||||||
IboxComponent,
|
IboxComponent,
|
||||||
|
CustomWidgetConfigComponent,
|
||||||
|
|
||||||
// Vendor
|
// Vendor
|
||||||
],
|
],
|
||||||
|
@ -6,6 +6,7 @@ import { VideoWidgetWrapperComponent } from "./widget_wrappers/video/video.compo
|
|||||||
import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.component";
|
import { JitsiWidgetWrapperComponent } from "./widget_wrappers/jitsi/jitsi.component";
|
||||||
import { GCalWidgetWrapperComponent } from "./widget_wrappers/gcal/gcal.component";
|
import { GCalWidgetWrapperComponent } from "./widget_wrappers/gcal/gcal.component";
|
||||||
import { RiotHomeComponent } from "./riot/riot-home/home.component";
|
import { RiotHomeComponent } from "./riot/riot-home/home.component";
|
||||||
|
import { CustomWidgetConfigComponent } from "./configs/widget/custom/custom.widget.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{path: "", component: HomeComponent},
|
{path: "", component: HomeComponent},
|
||||||
@ -21,14 +22,13 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "widget",
|
path: "widget",
|
||||||
children: [],
|
children: [
|
||||||
// children: [
|
{
|
||||||
// {
|
path: "custom",
|
||||||
// path: "custom",
|
component: CustomWidgetConfigComponent,
|
||||||
// component: NewTestWidgetComponent,
|
data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"}
|
||||||
// data: {breadcrumb: "Custom Widgets", name: "Custom Widgets"}
|
},
|
||||||
// },
|
],
|
||||||
// ],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
58
web/app/configs/widget/custom/custom.widget.component.html
Normal file
58
web/app/configs/widget/custom/custom.widget.component.html
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<my-ibox title="Add {{ defaultName }}">
|
||||||
|
<div class="my-ibox-content">
|
||||||
|
<form (submit)="addWidget()" novalidate name="addForm">
|
||||||
|
<label class="label-block">
|
||||||
|
Widget Name
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
placeholder="{{ defaultName }}"
|
||||||
|
[(ngModel)]="newWidget.dimension.newName" name="widget-name-new"
|
||||||
|
[disabled]="isUpdating"/>
|
||||||
|
</label>
|
||||||
|
<label class="label-block">
|
||||||
|
Widget URL
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
placeholder="https://matrix.org"
|
||||||
|
[(ngModel)]="newWidget.dimension.newUrl" name="widget-url-new"
|
||||||
|
[disabled]="isUpdating"/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-sm btn-success" [disabled]="isUpdating">
|
||||||
|
<i class="fa fa-plus"></i> Add Widget
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</my-ibox>
|
||||||
|
|
||||||
|
<my-ibox *ngFor="let widget of widgets trackById"
|
||||||
|
[isCollapsible]="true" [defaultCollapsed]="widget.id !== defaultExpandedWidgetId"
|
||||||
|
title="{{ widget.name || widget.url || defaultName }}">
|
||||||
|
<div class="my-ibox-content">
|
||||||
|
<form (submit)="saveWidget(widget)" novalidate name="addForm">
|
||||||
|
<label class="label-block">
|
||||||
|
Widget Name
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
placeholder="{{ defaultName }}"
|
||||||
|
[(ngModel)]="widget.dimension.newName" name="widget-name-{{widget.id}}"
|
||||||
|
[disabled]="isUpdating"/>
|
||||||
|
</label>
|
||||||
|
<label class="label-block">
|
||||||
|
Widget URL
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
placeholder="https://matrix.org"
|
||||||
|
[(ngModel)]="widget.dimension.newUrl" name="widget-url-{{widget.id}}"
|
||||||
|
[disabled]="isUpdating"/>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-sm btn-primary" [disabled]="isUpdating">
|
||||||
|
<i class="fa fa-save"></i> Save Widget
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-danger" [disabled]="isUpdating">
|
||||||
|
<i class="fa fa-times"></i> Remove Widget
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-white" [disabled]="isUpdating" (click)="resetWidget(widget)"
|
||||||
|
*ngIf="hasChanges(widget)">
|
||||||
|
<i class="fa fa-reset"></i> Undo Changes
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</my-ibox>
|
13
web/app/configs/widget/custom/custom.widget.component.ts
Normal file
13
web/app/configs/widget/custom/custom.widget.component.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { NewWidgetComponent } from "../widget.component";
|
||||||
|
import { WIDGET_CUSTOM } from "../../../shared/models/widget";
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "custom.widget.component.html",
|
||||||
|
styleUrls: ["custom.widget.component.scss"],
|
||||||
|
})
|
||||||
|
export class CustomWidgetConfigComponent extends NewWidgetComponent {
|
||||||
|
constructor() {
|
||||||
|
super(WIDGET_CUSTOM, "Custom Widget", "generic");
|
||||||
|
}
|
||||||
|
}
|
@ -18,8 +18,8 @@ export class NewWidgetComponent {
|
|||||||
public isUpdating = false;
|
public isUpdating = false;
|
||||||
public widgets: EditableWidget[];
|
public widgets: EditableWidget[];
|
||||||
public newWidget: EditableWidget;
|
public newWidget: EditableWidget;
|
||||||
|
public defaultExpandedWidgetId: string;
|
||||||
|
|
||||||
private toggledWidgetIds: string[] = [];
|
|
||||||
private scalarWrapperUrls: string[] = [];
|
private scalarWrapperUrls: string[] = [];
|
||||||
private wrapperUrl = "";
|
private wrapperUrl = "";
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export class NewWidgetComponent {
|
|||||||
protected OnWidgetAfterDelete = new EventEmitter<EditableWidget>();
|
protected OnWidgetAfterDelete = new EventEmitter<EditableWidget>();
|
||||||
|
|
||||||
constructor(private widgetTypes: string[],
|
constructor(private widgetTypes: string[],
|
||||||
private defaultName: string,
|
public defaultName: string,
|
||||||
private wrapperId = "generic",
|
private wrapperId = "generic",
|
||||||
private scalarWrapperId = null) {
|
private scalarWrapperId = null) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
@ -64,6 +64,12 @@ export class NewWidgetComponent {
|
|||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
|
|
||||||
|
// We reset after discovering to ensure that the widget component can correctly
|
||||||
|
// set the state of the widget prior to us unpacking it (again)
|
||||||
|
for (let widget of this.widgets) {
|
||||||
|
this.resetWidget(widget);
|
||||||
|
}
|
||||||
|
|
||||||
// See if we should request editing a particular widget
|
// See if we should request editing a particular widget
|
||||||
if (SessionStorage.editWidgetId && SessionStorage.editsRequested === 1) {
|
if (SessionStorage.editWidgetId && SessionStorage.editsRequested === 1) {
|
||||||
let editWidget: EditableWidget = null;
|
let editWidget: EditableWidget = null;
|
||||||
@ -78,7 +84,7 @@ export class NewWidgetComponent {
|
|||||||
console.log("Requesting edit for " + editWidget.id);
|
console.log("Requesting edit for " + editWidget.id);
|
||||||
this.widgets = [editWidget];
|
this.widgets = [editWidget];
|
||||||
otherWidgets.forEach(w => this.widgets.push(w));
|
otherWidgets.forEach(w => this.widgets.push(w));
|
||||||
this.editWidget(editWidget);
|
this.defaultExpandedWidgetId = editWidget.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -171,7 +177,6 @@ export class NewWidgetComponent {
|
|||||||
* @return {string} The unwrapped URL
|
* @return {string} The unwrapped URL
|
||||||
*/
|
*/
|
||||||
private unwrapUrl(url: string): string {
|
private unwrapUrl(url: string): string {
|
||||||
console.log(this.scalarWrapperUrls);
|
|
||||||
if (!this.wrapperUrl) return url;
|
if (!this.wrapperUrl) return url;
|
||||||
|
|
||||||
const urls = [this.wrapperUrl].concat(this.scalarWrapperUrls);
|
const urls = [this.wrapperUrl].concat(this.scalarWrapperUrls);
|
||||||
@ -225,6 +230,11 @@ export class NewWidgetComponent {
|
|||||||
* with a new widget.
|
* with a new widget.
|
||||||
*/
|
*/
|
||||||
public addWidget(): Promise<any> {
|
public addWidget(): Promise<any> {
|
||||||
|
if (!this.newWidget.dimension.newUrl || this.newWidget.dimension.newUrl.trim().length === 0) {
|
||||||
|
this.toaster.pop("warning", "Please enter a URL for the widget");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.packWidget(this.newWidget);
|
this.packWidget(this.newWidget);
|
||||||
|
|
||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
@ -260,7 +270,6 @@ export class NewWidgetComponent {
|
|||||||
this.isUpdating = true;
|
this.isUpdating = true;
|
||||||
this.OnWidgetBeforeEdit.emit(widget);
|
this.OnWidgetBeforeEdit.emit(widget);
|
||||||
return this.scalarApi.setWidget(SessionStorage.roomId, widget)
|
return this.scalarApi.setWidget(SessionStorage.roomId, widget)
|
||||||
.then(() => this.toggleWidget(widget))
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.isUpdating = false;
|
this.isUpdating = false;
|
||||||
this.OnWidgetAfterEdit.emit(widget);
|
this.OnWidgetAfterEdit.emit(widget);
|
||||||
@ -296,38 +305,28 @@ export class NewWidgetComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts a widget in the edit state.
|
* Resets a widget to before it had changes made to it
|
||||||
* @param {EditableWidget} widget
|
* @param {EditableWidget} widget The widget to reset
|
||||||
*/
|
*/
|
||||||
public editWidget(widget: EditableWidget) {
|
public resetWidget(widget: EditableWidget) {
|
||||||
this.toggleWidget(widget, "edit");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Toggles a widget between the "edit" and "canceled" state. If a targetState is
|
|
||||||
* defined, the widget is forced into that state.
|
|
||||||
* @param {EditableWidget} widget The widget to set the state of.
|
|
||||||
* @param {"edit"|"cancel"|null} targetState The target state, optional
|
|
||||||
*/
|
|
||||||
public toggleWidget(widget: EditableWidget, targetState: "edit" | "cancel" | null = null) {
|
|
||||||
let idx = this.toggledWidgetIds.indexOf(widget.id);
|
|
||||||
if (targetState === null) targetState = idx === -1 ? "edit" : "cancel";
|
|
||||||
|
|
||||||
if (targetState === "edit") {
|
|
||||||
this.unpackWidget(widget);
|
this.unpackWidget(widget);
|
||||||
this.OnWidgetPreparedForEdit.emit(widget);
|
this.OnWidgetPreparedForEdit.emit(widget);
|
||||||
|
|
||||||
if (idx === -1) this.toggledWidgetIds.push(widget.id);
|
|
||||||
}
|
|
||||||
else this.toggledWidgetIds.splice(idx, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a widget is in the edit state
|
* Determines if a widget has had any changes made to it
|
||||||
* @param {EditableWidget} widget The widget to check
|
* @param {EditableWidget} widget The widget to check
|
||||||
* @returns {boolean} true if the widget is in the edit state
|
* @returns {boolean} True if the widget has been edited
|
||||||
*/
|
*/
|
||||||
public isWidgetToggled(widget: EditableWidget) {
|
public hasChanges(widget: EditableWidget):boolean {
|
||||||
return this.toggledWidgetIds.indexOf(widget.id) !== -1;
|
if (widget.dimension.newUrl !== this.unwrapUrl(widget.url)) return true;
|
||||||
|
if (widget.dimension.newName !== widget.name) return true;
|
||||||
|
if (widget.dimension.newTitle !== widget.data.title) return true;
|
||||||
|
|
||||||
|
const currentData = JSON.parse(JSON.stringify(widget.data || "{}"));
|
||||||
|
const newData = JSON.parse(JSON.stringify(widget.dimension.newData || "{}"));
|
||||||
|
if (currentData !== newData) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,3 +30,7 @@ body {
|
|||||||
button {
|
button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-block {
|
||||||
|
display: block;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user