@memberjunction/ng-feedback 0.0.1 → 5.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/feedback-button.component.d.ts +59 -0
- package/dist/lib/components/feedback-button.component.d.ts.map +1 -0
- package/dist/lib/components/feedback-button.component.js +108 -0
- package/dist/lib/components/feedback-button.component.js.map +1 -0
- package/dist/lib/components/feedback-form.component.d.ts +101 -0
- package/dist/lib/components/feedback-form.component.d.ts.map +1 -0
- package/dist/lib/components/feedback-form.component.js +920 -0
- package/dist/lib/components/feedback-form.component.js.map +1 -0
- package/dist/lib/feedback.config.d.ts +67 -0
- package/dist/lib/feedback.config.d.ts.map +1 -0
- package/dist/lib/feedback.config.js +33 -0
- package/dist/lib/feedback.config.js.map +1 -0
- package/dist/lib/feedback.constants.d.ts +14 -0
- package/dist/lib/feedback.constants.d.ts.map +1 -0
- package/dist/lib/feedback.constants.js +60 -0
- package/dist/lib/feedback.constants.js.map +1 -0
- package/dist/lib/feedback.module.d.ts +77 -0
- package/dist/lib/feedback.module.d.ts.map +1 -0
- package/dist/lib/feedback.module.js +121 -0
- package/dist/lib/feedback.module.js.map +1 -0
- package/dist/lib/feedback.types.d.ts +73 -0
- package/dist/lib/feedback.types.d.ts.map +1 -0
- package/dist/lib/feedback.types.js +2 -0
- package/dist/lib/feedback.types.js.map +1 -0
- package/dist/lib/services/feedback-dialog.service.d.ts +85 -0
- package/dist/lib/services/feedback-dialog.service.d.ts.map +1 -0
- package/dist/lib/services/feedback-dialog.service.js +177 -0
- package/dist/lib/services/feedback-dialog.service.js.map +1 -0
- package/dist/lib/services/feedback.service.d.ts +63 -0
- package/dist/lib/services/feedback.service.d.ts.map +1 -0
- package/dist/lib/services/feedback.service.js +240 -0
- package/dist/lib/services/feedback.service.js.map +1 -0
- package/dist/public-api.d.ts +9 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +18 -0
- package/dist/public-api.js.map +1 -0
- package/package.json +37 -7
- package/README.md +0 -45
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Injectable, Inject, createComponent } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { FeedbackFormComponent } from '../components/feedback-form.component';
|
|
4
|
+
import { FEEDBACK_CONFIG } from '../feedback.config';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
/**
|
|
7
|
+
* Lightweight dialog reference replacing Kendo's DialogRef
|
|
8
|
+
*/
|
|
9
|
+
export class FeedbackDialogRef {
|
|
10
|
+
destroyFn;
|
|
11
|
+
resultSubject = new Subject();
|
|
12
|
+
/** Observable that emits when the dialog closes */
|
|
13
|
+
Result = this.resultSubject.asObservable();
|
|
14
|
+
constructor(destroyFn) {
|
|
15
|
+
this.destroyFn = destroyFn;
|
|
16
|
+
}
|
|
17
|
+
/** Close the dialog programmatically */
|
|
18
|
+
Close() {
|
|
19
|
+
this.destroyFn();
|
|
20
|
+
}
|
|
21
|
+
/** @internal Emit the result and complete */
|
|
22
|
+
_emitResult(result) {
|
|
23
|
+
this.resultSubject.next(result);
|
|
24
|
+
this.resultSubject.complete();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Service for managing the feedback dialog lifecycle
|
|
29
|
+
*/
|
|
30
|
+
export class FeedbackDialogService {
|
|
31
|
+
appRef;
|
|
32
|
+
injector;
|
|
33
|
+
config;
|
|
34
|
+
activeDialogRef = null;
|
|
35
|
+
activeComponentRef = null;
|
|
36
|
+
constructor(appRef, injector, config) {
|
|
37
|
+
this.appRef = appRef;
|
|
38
|
+
this.injector = injector;
|
|
39
|
+
this.config = config;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Open the feedback dialog
|
|
43
|
+
* @param options - Dialog configuration options
|
|
44
|
+
* @returns FeedbackDialogRef for the opened dialog
|
|
45
|
+
*/
|
|
46
|
+
OpenFeedbackDialog(options) {
|
|
47
|
+
// Close any existing dialog first
|
|
48
|
+
this.closeActiveDialog();
|
|
49
|
+
// Create the component dynamically
|
|
50
|
+
const componentRef = createComponent(FeedbackFormComponent, {
|
|
51
|
+
environmentInjector: this.injector
|
|
52
|
+
});
|
|
53
|
+
// Configure the component instance
|
|
54
|
+
const instance = componentRef.instance;
|
|
55
|
+
if (options?.prefilledCategory) {
|
|
56
|
+
instance.PrefilledCategory = options.prefilledCategory;
|
|
57
|
+
}
|
|
58
|
+
if (options?.prefilledTitle) {
|
|
59
|
+
instance.PrefilledTitle = options.prefilledTitle;
|
|
60
|
+
}
|
|
61
|
+
if (options?.contextData) {
|
|
62
|
+
instance.ContextData = options.contextData;
|
|
63
|
+
}
|
|
64
|
+
if (options?.currentPage) {
|
|
65
|
+
instance.CurrentPage = options.currentPage;
|
|
66
|
+
}
|
|
67
|
+
// Attach to Angular's change detection
|
|
68
|
+
this.appRef.attachView(componentRef.hostView);
|
|
69
|
+
// Add to DOM
|
|
70
|
+
const hostElement = componentRef.hostView.rootNodes[0];
|
|
71
|
+
document.body.appendChild(hostElement);
|
|
72
|
+
// Create the dialog ref with a cleanup function
|
|
73
|
+
const dialogRef = new FeedbackDialogRef(() => {
|
|
74
|
+
this.destroyComponent(componentRef, hostElement);
|
|
75
|
+
});
|
|
76
|
+
// Listen for dialog close from the form component
|
|
77
|
+
instance.DialogClosed.subscribe((result) => {
|
|
78
|
+
dialogRef._emitResult(result);
|
|
79
|
+
this.destroyComponent(componentRef, hostElement);
|
|
80
|
+
});
|
|
81
|
+
// Track active dialog
|
|
82
|
+
this.activeDialogRef = dialogRef;
|
|
83
|
+
this.activeComponentRef = componentRef;
|
|
84
|
+
return dialogRef;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Open dialog pre-configured for bug reporting
|
|
88
|
+
*/
|
|
89
|
+
OpenBugReportDialog(options) {
|
|
90
|
+
return this.OpenFeedbackDialog({
|
|
91
|
+
...options,
|
|
92
|
+
prefilledCategory: 'bug'
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Open dialog pre-configured for feature requests
|
|
97
|
+
*/
|
|
98
|
+
OpenFeatureRequestDialog(options) {
|
|
99
|
+
return this.OpenFeedbackDialog({
|
|
100
|
+
...options,
|
|
101
|
+
prefilledCategory: 'feature'
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Attach a screenshot to the currently open feedback dialog.
|
|
106
|
+
* Called asynchronously after the dialog is already open.
|
|
107
|
+
*/
|
|
108
|
+
AttachScreenshot(screenshotDataUrl) {
|
|
109
|
+
if (this.activeComponentRef && !this.activeComponentRef.hostView.destroyed) {
|
|
110
|
+
const instance = this.activeComponentRef.instance;
|
|
111
|
+
instance.ScreenshotDataUrl = screenshotDataUrl;
|
|
112
|
+
instance.IsCapturingScreenshot = false;
|
|
113
|
+
// Don't add to ContextData — user must opt in via IncludeScreenshot()
|
|
114
|
+
this.activeComponentRef.changeDetectorRef.detectChanges();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Stop the screenshot loading indicator if capture failed or returned nothing.
|
|
119
|
+
*/
|
|
120
|
+
StopScreenshotLoading() {
|
|
121
|
+
if (this.activeComponentRef && !this.activeComponentRef.hostView.destroyed) {
|
|
122
|
+
this.activeComponentRef.instance.IsCapturingScreenshot = false;
|
|
123
|
+
this.activeComponentRef.changeDetectorRef.detectChanges();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Close all open feedback dialogs
|
|
128
|
+
*/
|
|
129
|
+
CloseAllDialogs() {
|
|
130
|
+
this.closeActiveDialog();
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Clean up a component and remove from DOM
|
|
134
|
+
*/
|
|
135
|
+
destroyComponent(componentRef, hostElement) {
|
|
136
|
+
if (this.activeComponentRef === componentRef) {
|
|
137
|
+
this.activeComponentRef = null;
|
|
138
|
+
this.activeDialogRef = null;
|
|
139
|
+
}
|
|
140
|
+
if (!componentRef.hostView.destroyed) {
|
|
141
|
+
this.appRef.detachView(componentRef.hostView);
|
|
142
|
+
componentRef.destroy();
|
|
143
|
+
}
|
|
144
|
+
if (hostElement.parentNode) {
|
|
145
|
+
hostElement.parentNode.removeChild(hostElement);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Close the active dialog if one exists
|
|
150
|
+
*/
|
|
151
|
+
closeActiveDialog() {
|
|
152
|
+
if (this.activeComponentRef && this.activeDialogRef) {
|
|
153
|
+
try {
|
|
154
|
+
this.activeComponentRef.instance.DialogVisible = false;
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// Component might already be destroyed
|
|
158
|
+
}
|
|
159
|
+
if (!this.activeComponentRef.hostView.destroyed) {
|
|
160
|
+
const hostElement = this.activeComponentRef.hostView.rootNodes[0];
|
|
161
|
+
this.destroyComponent(this.activeComponentRef, hostElement);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
static ɵfac = function FeedbackDialogService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FeedbackDialogService)(i0.ɵɵinject(i0.ApplicationRef), i0.ɵɵinject(i0.EnvironmentInjector), i0.ɵɵinject(FEEDBACK_CONFIG)); };
|
|
166
|
+
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FeedbackDialogService, factory: FeedbackDialogService.ɵfac, providedIn: 'root' });
|
|
167
|
+
}
|
|
168
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeedbackDialogService, [{
|
|
169
|
+
type: Injectable,
|
|
170
|
+
args: [{
|
|
171
|
+
providedIn: 'root'
|
|
172
|
+
}]
|
|
173
|
+
}], () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }, { type: undefined, decorators: [{
|
|
174
|
+
type: Inject,
|
|
175
|
+
args: [FEEDBACK_CONFIG]
|
|
176
|
+
}] }], null); })();
|
|
177
|
+
//# sourceMappingURL=feedback-dialog.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback-dialog.service.js","sourceRoot":"","sources":["../../../src/lib/services/feedback-dialog.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { FeedbackSubmission, FeedbackResponse, FeedbackCategory, FeedbackSeverity } from '../feedback.types';
|
|
3
|
+
import { FeedbackConfig } from '../feedback.config';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
/**
|
|
6
|
+
* Service for submitting feedback via GraphQL
|
|
7
|
+
*/
|
|
8
|
+
export declare class FeedbackService {
|
|
9
|
+
private config;
|
|
10
|
+
/** Observable for tracking submission state */
|
|
11
|
+
private _isSubmitting$;
|
|
12
|
+
IsSubmitting$: Observable<boolean>;
|
|
13
|
+
constructor(config: FeedbackConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Get the current configuration
|
|
16
|
+
*/
|
|
17
|
+
GetConfig(): FeedbackConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Check if feedback is enabled for this organization.
|
|
20
|
+
*/
|
|
21
|
+
IsEnabled(): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* Classify feedback using an LLM to suggest category and severity.
|
|
24
|
+
* Returns null if classification fails — callers should fall back to manual selection.
|
|
25
|
+
*/
|
|
26
|
+
Classify(title: string, description: string): Promise<{
|
|
27
|
+
category: FeedbackCategory;
|
|
28
|
+
severity: FeedbackSeverity;
|
|
29
|
+
} | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Submit feedback via GraphQL mutation
|
|
32
|
+
* @param data - The feedback submission data
|
|
33
|
+
* @returns Observable with the server response
|
|
34
|
+
*/
|
|
35
|
+
Submit(data: FeedbackSubmission): Observable<FeedbackResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Execute the GraphQL mutation
|
|
38
|
+
*/
|
|
39
|
+
private executeGraphQLMutation;
|
|
40
|
+
/**
|
|
41
|
+
* Process the GraphQL result into a FeedbackResponse
|
|
42
|
+
*/
|
|
43
|
+
private processResult;
|
|
44
|
+
/**
|
|
45
|
+
* Enrich submission with auto-captured environment data and authenticated user info
|
|
46
|
+
*/
|
|
47
|
+
private enrichSubmission;
|
|
48
|
+
/**
|
|
49
|
+
* Detect environment from the current URL hostname
|
|
50
|
+
*/
|
|
51
|
+
private detectEnvironment;
|
|
52
|
+
/**
|
|
53
|
+
* Convert camelCase submission to PascalCase GraphQL input
|
|
54
|
+
*/
|
|
55
|
+
private convertToGraphQLInput;
|
|
56
|
+
/**
|
|
57
|
+
* Handle errors
|
|
58
|
+
*/
|
|
59
|
+
private handleError;
|
|
60
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FeedbackService, never>;
|
|
61
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<FeedbackService>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=feedback.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/feedback.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAqC,MAAM,MAAM,CAAC;AAIrE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAuB,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClI,OAAO,EAAE,cAAc,EAAmB,MAAM,oBAAoB,CAAC;;AAuCrE;;GAEG;AACH,qBAGa,eAAe;IAMC,OAAO,CAAC,MAAM;IALzC,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAAuC;IACtD,aAAa,sBAAsC;gBAGvB,MAAM,EAAE,cAAc;IAGzD;;OAEG;IACI,SAAS,IAAI,cAAc;IAIlC;;OAEG;IACU,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAU1C;;;OAGG;IACU,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,gBAAgB,CAAC;QAAC,QAAQ,EAAE,gBAAgB,CAAA;KAAE,GAAG,IAAI,CAAC;IAmBrI;;;;OAIG;IACI,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU,CAAC,gBAAgB,CAAC;IAwBrE;;OAEG;YACW,sBAAsB;IAOpC;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAoBxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0B7B;;OAEG;IACH,OAAO,CAAC,WAAW;yCAvLR,eAAe;6CAAf,eAAe;CAyM3B"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Injectable, Inject } from '@angular/core';
|
|
2
|
+
import { from, BehaviorSubject, throwError } from 'rxjs';
|
|
3
|
+
import { catchError, tap, map } from 'rxjs/operators';
|
|
4
|
+
import { gql } from '@memberjunction/graphql-dataprovider';
|
|
5
|
+
import { Metadata } from '@memberjunction/core';
|
|
6
|
+
import { FEEDBACK_CONFIG } from '../feedback.config';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
/**
|
|
9
|
+
* GraphQL mutation for classifying feedback via LLM
|
|
10
|
+
*/
|
|
11
|
+
const CLASSIFY_FEEDBACK_MUTATION = gql `
|
|
12
|
+
mutation ClassifyFeedback($input: ClassifyFeedbackInput!) {
|
|
13
|
+
ClassifyFeedback(input: $input) {
|
|
14
|
+
Success
|
|
15
|
+
Category
|
|
16
|
+
Severity
|
|
17
|
+
Error
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
/**
|
|
22
|
+
* GraphQL query for checking if feedback is enabled
|
|
23
|
+
*/
|
|
24
|
+
const FEEDBACK_ENABLED_QUERY = gql `
|
|
25
|
+
query FeedbackEnabled {
|
|
26
|
+
FeedbackEnabled
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
/**
|
|
30
|
+
* GraphQL mutation for submitting feedback
|
|
31
|
+
*/
|
|
32
|
+
const SUBMIT_FEEDBACK_MUTATION = gql `
|
|
33
|
+
mutation SubmitFeedback($input: SubmitFeedbackInput!) {
|
|
34
|
+
SubmitFeedback(input: $input) {
|
|
35
|
+
Success
|
|
36
|
+
IssueNumber
|
|
37
|
+
IssueUrl
|
|
38
|
+
Error
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
`;
|
|
42
|
+
/**
|
|
43
|
+
* Service for submitting feedback via GraphQL
|
|
44
|
+
*/
|
|
45
|
+
export class FeedbackService {
|
|
46
|
+
config;
|
|
47
|
+
/** Observable for tracking submission state */
|
|
48
|
+
_isSubmitting$ = new BehaviorSubject(false);
|
|
49
|
+
IsSubmitting$ = this._isSubmitting$.asObservable();
|
|
50
|
+
constructor(config) {
|
|
51
|
+
this.config = config;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the current configuration
|
|
55
|
+
*/
|
|
56
|
+
GetConfig() {
|
|
57
|
+
return this.config;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if feedback is enabled for this organization.
|
|
61
|
+
*/
|
|
62
|
+
async IsEnabled() {
|
|
63
|
+
try {
|
|
64
|
+
const provider = Metadata.Provider;
|
|
65
|
+
const result = await provider.ExecuteGQL(FEEDBACK_ENABLED_QUERY, {});
|
|
66
|
+
return result?.FeedbackEnabled ?? true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return true; // Default to enabled if check fails
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Classify feedback using an LLM to suggest category and severity.
|
|
74
|
+
* Returns null if classification fails — callers should fall back to manual selection.
|
|
75
|
+
*/
|
|
76
|
+
async Classify(title, description) {
|
|
77
|
+
try {
|
|
78
|
+
const provider = Metadata.Provider;
|
|
79
|
+
const result = await provider.ExecuteGQL(CLASSIFY_FEEDBACK_MUTATION, {
|
|
80
|
+
input: { Title: title, Description: description }
|
|
81
|
+
});
|
|
82
|
+
if (result?.ClassifyFeedback?.Success && result.ClassifyFeedback.Category && result.ClassifyFeedback.Severity) {
|
|
83
|
+
return {
|
|
84
|
+
category: result.ClassifyFeedback.Category,
|
|
85
|
+
severity: result.ClassifyFeedback.Severity
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Submit feedback via GraphQL mutation
|
|
96
|
+
* @param data - The feedback submission data
|
|
97
|
+
* @returns Observable with the server response
|
|
98
|
+
*/
|
|
99
|
+
Submit(data) {
|
|
100
|
+
this._isSubmitting$.next(true);
|
|
101
|
+
// Enrich with auto-captured data
|
|
102
|
+
const enrichedData = this.enrichSubmission(data);
|
|
103
|
+
// Convert to GraphQL input format (PascalCase)
|
|
104
|
+
const input = this.convertToGraphQLInput(enrichedData);
|
|
105
|
+
// Execute GraphQL mutation
|
|
106
|
+
const promise = this.executeGraphQLMutation(input);
|
|
107
|
+
return from(promise).pipe(map((result) => this.processResult(result)), tap(() => {
|
|
108
|
+
this._isSubmitting$.next(false);
|
|
109
|
+
}), catchError((error) => {
|
|
110
|
+
this._isSubmitting$.next(false);
|
|
111
|
+
return this.handleError(error);
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Execute the GraphQL mutation
|
|
116
|
+
*/
|
|
117
|
+
async executeGraphQLMutation(input) {
|
|
118
|
+
const variables = { input };
|
|
119
|
+
const provider = Metadata.Provider;
|
|
120
|
+
const result = await provider.ExecuteGQL(SUBMIT_FEEDBACK_MUTATION, variables);
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Process the GraphQL result into a FeedbackResponse
|
|
125
|
+
*/
|
|
126
|
+
processResult(result) {
|
|
127
|
+
if (!result?.SubmitFeedback) {
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: 'Invalid response from server'
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const data = result.SubmitFeedback;
|
|
134
|
+
return {
|
|
135
|
+
success: data.Success,
|
|
136
|
+
issueNumber: data.IssueNumber,
|
|
137
|
+
issueUrl: data.IssueUrl,
|
|
138
|
+
error: data.Error
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Enrich submission with auto-captured environment data and authenticated user info
|
|
143
|
+
*/
|
|
144
|
+
enrichSubmission(data) {
|
|
145
|
+
const md = new Metadata();
|
|
146
|
+
const currentUser = md.CurrentUser;
|
|
147
|
+
return {
|
|
148
|
+
...data,
|
|
149
|
+
// Auto-populate from authenticated user (can be overridden by explicit values)
|
|
150
|
+
userId: data.userId || currentUser?.ID,
|
|
151
|
+
name: data.name || currentUser?.Name,
|
|
152
|
+
email: data.email || currentUser?.Email,
|
|
153
|
+
// Auto-capture environment data
|
|
154
|
+
environment: data.environment || this.detectEnvironment(),
|
|
155
|
+
userAgent: data.userAgent || navigator.userAgent,
|
|
156
|
+
screenSize: data.screenSize || `${window.innerWidth}x${window.innerHeight}`,
|
|
157
|
+
appName: data.appName || this.config.appName,
|
|
158
|
+
appVersion: data.appVersion || this.config.appVersion,
|
|
159
|
+
timestamp: data.timestamp || new Date().toISOString()
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Detect environment from the current URL hostname
|
|
164
|
+
*/
|
|
165
|
+
detectEnvironment() {
|
|
166
|
+
const hostname = window.location.hostname;
|
|
167
|
+
if (hostname === 'localhost' || hostname === '127.0.0.1') {
|
|
168
|
+
return 'local';
|
|
169
|
+
}
|
|
170
|
+
if (hostname.includes('staging') || hostname.includes('stage')) {
|
|
171
|
+
return 'staging';
|
|
172
|
+
}
|
|
173
|
+
if (hostname.includes('dev')) {
|
|
174
|
+
return 'development';
|
|
175
|
+
}
|
|
176
|
+
return 'production';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Convert camelCase submission to PascalCase GraphQL input
|
|
180
|
+
*/
|
|
181
|
+
convertToGraphQLInput(data) {
|
|
182
|
+
return {
|
|
183
|
+
Title: data.title,
|
|
184
|
+
Description: data.description,
|
|
185
|
+
Category: data.category,
|
|
186
|
+
StepsToReproduce: data.stepsToReproduce,
|
|
187
|
+
ExpectedBehavior: data.expectedBehavior,
|
|
188
|
+
ActualBehavior: data.actualBehavior,
|
|
189
|
+
Severity: data.severity,
|
|
190
|
+
UseCase: data.useCase,
|
|
191
|
+
ProposedSolution: data.proposedSolution,
|
|
192
|
+
Email: data.email,
|
|
193
|
+
Name: data.name,
|
|
194
|
+
Environment: data.environment,
|
|
195
|
+
AffectedArea: data.affectedArea,
|
|
196
|
+
CurrentPage: data.currentPage,
|
|
197
|
+
UserAgent: data.userAgent,
|
|
198
|
+
ScreenSize: data.screenSize,
|
|
199
|
+
AppName: data.appName,
|
|
200
|
+
AppVersion: data.appVersion,
|
|
201
|
+
UserId: data.userId,
|
|
202
|
+
Timestamp: data.timestamp,
|
|
203
|
+
Metadata: data.metadata ? JSON.stringify(data.metadata) : undefined
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Handle errors
|
|
208
|
+
*/
|
|
209
|
+
handleError(error) {
|
|
210
|
+
let errorMessage = 'An error occurred while submitting feedback.';
|
|
211
|
+
if (error.message) {
|
|
212
|
+
// Check for specific error types
|
|
213
|
+
if (error.message.includes('rate limit') || error.message.includes('Too many')) {
|
|
214
|
+
errorMessage = 'Too many requests. Please try again later.';
|
|
215
|
+
}
|
|
216
|
+
else if (error.message.includes('Validation')) {
|
|
217
|
+
errorMessage = error.message;
|
|
218
|
+
}
|
|
219
|
+
else if (error.message.includes('not configured')) {
|
|
220
|
+
errorMessage = 'Feedback system is not configured. Please contact support.';
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
errorMessage = error.message;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return throwError(() => new Error(errorMessage));
|
|
227
|
+
}
|
|
228
|
+
static ɵfac = function FeedbackService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || FeedbackService)(i0.ɵɵinject(FEEDBACK_CONFIG)); };
|
|
229
|
+
static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: FeedbackService, factory: FeedbackService.ɵfac, providedIn: 'root' });
|
|
230
|
+
}
|
|
231
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeedbackService, [{
|
|
232
|
+
type: Injectable,
|
|
233
|
+
args: [{
|
|
234
|
+
providedIn: 'root'
|
|
235
|
+
}]
|
|
236
|
+
}], () => [{ type: undefined, decorators: [{
|
|
237
|
+
type: Inject,
|
|
238
|
+
args: [FEEDBACK_CONFIG]
|
|
239
|
+
}] }], null); })();
|
|
240
|
+
//# sourceMappingURL=feedback.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.service.js","sourceRoot":"","sources":["../../../src/lib/services/feedback.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './lib/feedback.module';
|
|
2
|
+
export * from './lib/feedback.types';
|
|
3
|
+
export * from './lib/feedback.constants';
|
|
4
|
+
export * from './lib/feedback.config';
|
|
5
|
+
export * from './lib/components/feedback-form.component';
|
|
6
|
+
export * from './lib/components/feedback-button.component';
|
|
7
|
+
export * from './lib/services/feedback.service';
|
|
8
|
+
export * from './lib/services/feedback-dialog.service';
|
|
9
|
+
//# sourceMappingURL=public-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,uBAAuB,CAAC;AAGtC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,uBAAuB,CAAC;AAGtC,cAAc,0CAA0C,CAAC;AACzD,cAAc,4CAA4C,CAAC;AAG3D,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Public API Surface of @memberjunction/ng-feedback
|
|
3
|
+
*/
|
|
4
|
+
// Module
|
|
5
|
+
export * from './lib/feedback.module';
|
|
6
|
+
// Types
|
|
7
|
+
export * from './lib/feedback.types';
|
|
8
|
+
// Constants
|
|
9
|
+
export * from './lib/feedback.constants';
|
|
10
|
+
// Configuration
|
|
11
|
+
export * from './lib/feedback.config';
|
|
12
|
+
// Components
|
|
13
|
+
export * from './lib/components/feedback-form.component';
|
|
14
|
+
export * from './lib/components/feedback-button.component';
|
|
15
|
+
// Services
|
|
16
|
+
export * from './lib/services/feedback.service';
|
|
17
|
+
export * from './lib/services/feedback-dialog.service';
|
|
18
|
+
//# sourceMappingURL=public-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,uBAAuB,CAAC;AAEtC,QAAQ;AACR,cAAc,sBAAsB,CAAC;AAErC,YAAY;AACZ,cAAc,0BAA0B,CAAC;AAEzC,gBAAgB;AAChB,cAAc,uBAAuB,CAAC;AAEtC,aAAa;AACb,cAAc,0CAA0C,CAAC;AACzD,cAAc,4CAA4C,CAAC;AAE3D,WAAW;AACX,cAAc,iCAAiC,CAAC;AAChD,cAAc,wCAAwC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-feedback",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
]
|
|
3
|
+
"version": "5.30.0",
|
|
4
|
+
"description": "MemberJunction: Feedback and bug reporting components for Angular applications",
|
|
5
|
+
"main": "./dist/public-api.js",
|
|
6
|
+
"typings": "./dist/public-api.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"/dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"No tests configured yet\"",
|
|
12
|
+
"build": "ngc",
|
|
13
|
+
"test:watch": "vitest"
|
|
14
|
+
},
|
|
15
|
+
"author": "MemberJunction.com",
|
|
16
|
+
"license": "ISC",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@angular/compiler": "21.1.3",
|
|
19
|
+
"@angular/compiler-cli": "21.1.3",
|
|
20
|
+
"vitest": "^4.0.18"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"@angular/common": "21.1.3",
|
|
24
|
+
"@angular/core": "21.1.3",
|
|
25
|
+
"@angular/forms": "21.1.3"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@memberjunction/core": "5.30.0",
|
|
29
|
+
"@memberjunction/graphql-dataprovider": "5.30.0",
|
|
30
|
+
"@memberjunction/ng-shared-generic": "5.30.0",
|
|
31
|
+
"@memberjunction/ng-ui-components": "5.30.0",
|
|
32
|
+
"tslib": "^2.8.1",
|
|
33
|
+
"rxjs": "~7.8.2"
|
|
34
|
+
},
|
|
35
|
+
"sideEffects": false,
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/MemberJunction/MJ"
|
|
39
|
+
}
|
|
10
40
|
}
|
package/README.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @memberjunction/ng-feedback
|
|
2
|
-
|
|
3
|
-
## ⚠️ IMPORTANT NOTICE ⚠️
|
|
4
|
-
|
|
5
|
-
**This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
|
|
6
|
-
|
|
7
|
-
This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@memberjunction/ng-feedback`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|