Skip to content

Commit 5d62997

Browse files
committed
add create mechanics
1 parent 6bb4741 commit 5d62997

File tree

3 files changed

+134
-9
lines changed

3 files changed

+134
-9
lines changed

rubberduckvba.client/src/app/components/edit-feature/edit-feature.component.html

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ <h6>Edit {{action == 'edit' ? 'description' : 'summary'}}</h6>
3535
<div class="row">
3636
<textarea *ngIf="action == 'edit'" [(ngModel)]="feature.description" type="text" maxlength="8000" rows="10" class="font-monospace text-nowrap p-1">
3737
</textarea>
38-
<textarea *ngIf="action == 'summary'" [(ngModel)]="feature.shortDescription" type="text" maxlength="8000" rows="5" class="font-monospace p-1">
38+
<textarea *ngIf="action == 'summary'" [(ngModel)]="feature.shortDescription" type="text" maxlength="1023" rows="5" class="font-monospace p-1">
3939
</textarea>
4040
</div>
4141
<div class="row">
@@ -64,6 +64,88 @@ <h4>{{feature.title}}</h4>
6464
</div>
6565
</ng-template>
6666

67+
<ng-template #createModal let-modal>
68+
<div *ngIf="feature">
69+
<div class="modal-header">
70+
<h4><img src="../../assets/vector-ducky-540.png" height="32">&nbsp;New {{subfeature.featureName}} Feature</h4>
71+
<button type="button" class="btn-close" aria-label="close" (click)="modal.dismiss('x')"></button>
72+
</div>
73+
<div class="modal-body">
74+
<div class="row">
75+
<div class="col-lg-6">
76+
77+
<div class="row">
78+
<label class="form-text fw-bold d-inline-block" for="nameBox">Name</label>
79+
<div>
80+
<small class="text-muted form-text">The name of the feature. Must be unique.</small>
81+
</div>
82+
<span class="m-2">
83+
<input id="nameBox" type="text" [(ngModel)]="subfeature.name" maxlength="255" [required]="true" class="p-1" />
84+
</span>
85+
</div>
86+
87+
<div class="row">
88+
<label class="form-text fw-bold d-inline-block" for="titleBox">Title</label>
89+
<div>
90+
<small class="text-muted form-text">The display name of the feature</small>
91+
</div>
92+
<span class="m-2">
93+
<input id="titleBox" type="text" [(ngModel)]="subfeature.title" maxlength="255" [required]="true" class="p-1" />
94+
</span>
95+
</div>
96+
97+
<div class="row">
98+
<label class="form-text fw-bold d-inline-block" for="isnewBox">
99+
<input id="isnewBox" type="checkbox" [(ngModel)]="subfeature.isNew" />
100+
New
101+
</label>
102+
<div>
103+
<small class="text-muted form-text">Whether the feature should have a 'new feature' marker on the site</small>
104+
</div>
105+
</div>
106+
107+
<div class="row">
108+
<label class="form-text fw-bold d-inline-block" for="summaryBox">Summary</label>
109+
<div>
110+
<small class="text-muted form-text">A short description of the feature.</small>
111+
</div>
112+
<span class="m-2">
113+
<textarea [(ngModel)]="subfeature.shortDescription" type="text" maxlength="1023" rows="5" class="font-monospace p-1 w-100"></textarea>
114+
</span>
115+
</div>
116+
117+
<div class="row">
118+
<label class="form-text fw-bold d-inline-block" for="summaryBox">Description</label>
119+
<div>
120+
<small class="text-muted form-text">A markdown document describing the feature in details.</small>
121+
</div>
122+
<span class="m-2">
123+
<textarea [(ngModel)]="subfeature.description" type="text" maxlength="8000" rows="5" class="font-monospace p-1 w-100"></textarea>
124+
</span>
125+
</div>
126+
</div>
127+
<div class="col-lg-6">
128+
<button type="button" class="btn btn-outline-secondary mb-2" (click)="onPreviewDescription()">
129+
<span><fa-icon [icon]="'refresh'"></fa-icon>&nbsp;Preview</span>
130+
</button>
131+
<div class="card">
132+
<div class="card-header">
133+
<h4 [innerText]="subfeature.title"></h4>
134+
</div>
135+
<div class="card-body">
136+
<p [innerHTML]="subfeature.descriptionPreview"></p>
137+
</div>
138+
</div>
139+
</div>
140+
</div>
141+
</div>
142+
<div class="modal-footer">
143+
<button type="button" class="btn btn-outline-primary" (click)="modal.dismiss('x')">Cancel</button>
144+
<button type="button" class="btn btn-success" (click)="onConfirmCreate()">Confirm</button>
145+
</div>
146+
</div>
147+
</ng-template>
148+
67149
<ng-template #deleteModal let-modal>
68150
<div *ngIf="feature">
69151
<div class="modal-header align-content-center">

rubberduckvba.client/src/app/components/edit-feature/edit-feature.component.ts

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export class EditFeatureComponent implements OnInit, OnChanges {
2424
private _action: AdminAction = AdminAction.Create;
2525

2626
@ViewChild('editModal', { read: TemplateRef }) editModal: TemplateRef<any> | undefined;
27+
@ViewChild('createModal', { read: TemplateRef }) createModal: TemplateRef<any> | undefined;
2728
@ViewChild('deleteModal', { read: TemplateRef }) deleteModal: TemplateRef<any> | undefined;
2829

2930
public modal = inject(NgbModal);
@@ -52,6 +53,8 @@ export class EditFeatureComponent implements OnInit, OnChanges {
5253
public onApplyChanges = new EventEmitter<SubFeatureViewModel>();
5354

5455

56+
public subfeature: EditSubFeatureViewModelClass = null!;
57+
5558
constructor(private fa: FaIconLibrary, private api: ApiClientService) {
5659
fa.addIconPacks(fas);
5760
}
@@ -63,29 +66,68 @@ export class EditFeatureComponent implements OnInit, OnChanges {
6366
}
6467

6568
public doAction(): void {
66-
const localModal = this.action == 'delete' ? this.deleteModal : this.editModal;
69+
const localModal = this.action == 'delete' ? this.deleteModal
70+
: this.action == 'create' ? this.createModal
71+
: this.editModal;
6772
const size = this.action == 'delete' ? 'modal-m' : 'modal-xl';
73+
74+
if (this.action == 'create') {
75+
const parentId = this.feature.id;
76+
const parentName = this.feature.name;
77+
const parentTitle = this.feature.title;
78+
79+
this.subfeature = new EditSubFeatureViewModelClass({
80+
dateInserted: '',
81+
dateUpdated: '',
82+
description: '',
83+
id: 0,
84+
isHidden: false,
85+
isNew: false,
86+
name: 'NewFeature1',
87+
title: 'New Feature',
88+
featureId: parentId,
89+
featureName: parentName,
90+
featureTitle: parentTitle,
91+
isCollapsed: false,
92+
isDetailsCollapsed: true,
93+
});
94+
}
95+
6896
this.modal.open(localModal, { modalDialogClass: size });
6997
}
7098

7199
public onConfirmChanges(): void {
72100
this.modal.dismissAll();
73101
this.api.saveFeature(this.feature).subscribe(saved => {
74-
this._feature.next(new EditSubFeatureViewModelClass(saved));
75-
this.onApplyChanges.emit(saved)
102+
window.location.reload();
103+
});
104+
}
105+
106+
public onConfirmCreate(): void {
107+
this.modal.dismissAll();
108+
this.api.saveFeature(this.subfeature).subscribe(saved => {
109+
window.location.reload();
76110
});
77111
}
78112

79113
public onPreviewDescription(): void {
80-
this.api.formatMarkdown(this.feature.description).subscribe((formatted: MarkdownContent) => {
81-
this.feature.descriptionPreview = formatted.content;
114+
const raw = this.action == 'create'
115+
? this.subfeature.description
116+
: this.feature.description;
117+
this.api.formatMarkdown(raw).subscribe((formatted: MarkdownContent) => {
118+
if (this.action == 'create') {
119+
this.subfeature.descriptionPreview = formatted.content;
120+
}
121+
else {
122+
this.feature.descriptionPreview = formatted.content;
123+
}
82124
});
83125
}
84126

85127
public onDeleteFeature(): void {
86128
this.modal.dismissAll();
87129
this.api.deleteFeature(this.feature).subscribe(() => {
88-
this._feature.next(new EditSubFeatureViewModelClass(null!));
130+
window.location.reload();
89131
});
90132
}
91133
}

rubberduckvba.client/src/app/model/feature.model.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export interface SubFeatureViewModel extends ViewModel {
2121

2222
title: string;
2323
description: string;
24+
shortDescription?: string | undefined;
2425
}
2526

2627
export interface XmlDocViewModel extends SubFeatureViewModel {
@@ -265,11 +266,13 @@ export class SubFeatureViewModelClass extends ViewModelBase implements SubFeatur
265266
featureTitle?: string | undefined;
266267
title: string;
267268
description: string;
269+
shortDescription?: string | undefined;
268270

269271
constructor(model: SubFeatureViewModel) {
270272
super(model);
271273
this.title = model.title;
272274
this.description = model.description;
275+
this.shortDescription = model.shortDescription;
273276
this.isDetailsCollapsed = true;
274277
this.featureId = model.featureId;
275278
this.featureName = model.featureName;
@@ -281,11 +284,9 @@ export class EditSubFeatureViewModelClass extends SubFeatureViewModelClass {
281284
super(model);
282285
this.isDetailsCollapsed = false;
283286
this.descriptionPreview = model.description;
284-
this.shortDescription = (model as FeatureViewModel)?.shortDescription;
285287
}
286288

287289
public descriptionPreview: string;
288-
public shortDescription?: string;
289290
}
290291

291292
export class InspectionViewModelClass extends SubFeatureViewModelClass implements InspectionViewModel {

0 commit comments

Comments
 (0)