@fluid-topics/ft-reader-feedback 2.1.20 → 2.1.21

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.
@@ -1,345 +1,6 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- import { html, nothing, } from "lit";
8
- import { property, query, state, } from "lit/decorators.js";
9
- import { parseDate, redux, } from "@fluid-topics/ft-wc-utils";
10
- import { styles } from "./ft-reader-feedback.styles";
11
- import { FtRatingType, } from "@fluid-topics/public-api";
12
- import { FtTypography } from "@fluid-topics/ft-typography";
13
- import { FtSwitch, FtSwitchOption, } from "@fluid-topics/ft-switch";
14
- import { FtTextArea } from "@fluid-topics/ft-text-area";
15
- import { repeat } from "lit/directives/repeat.js";
16
- import { FtButton } from "@fluid-topics/ft-button";
17
- import { defaultMessages, feedback, } from "./utils/IntegratedFeedbackComponentMessages";
18
- import { withI18n, } from "@fluid-topics/ft-i18n";
19
- import { FtTextField } from "@fluid-topics/ft-text-field";
20
- import { FtReaderComponent } from "@fluid-topics/ft-reader-context/build/registration";
21
- import { FtReaderFeatures } from "@fluid-topics/ft-reader-context";
22
- import { SendFeedbackEvent } from "./utils/events";
23
- export class FtReaderFeedback extends withI18n(FtReaderComponent) {
24
- constructor() {
25
- super();
26
- this.editorMode = false;
27
- this.hideTitle = false;
28
- this.withMoreOptionsButton = false;
29
- this.ratingAllowed = false;
30
- this.from = "";
31
- this.feedbackMessage = "";
32
- this.emptyStarIcon = "STAR";
33
- this.filledStarIcon = "STAR_PLAIN";
34
- this.emptyLikeIcon = "THUMBS_UP";
35
- this.filledLikeIcon = "THUMBS_UP_PLAIN";
36
- this.emptyDislikeIcon = "THUMBS_DOWN";
37
- this.filledDislikeIcon = "THUMBS_DOWN_PLAIN";
38
- this.addI18nContext(feedback, defaultMessages);
39
- }
40
- get canAccessFeedback() {
41
- var _a;
42
- return (_a = this.service) === null || _a === void 0 ? void 0 : _a.isFeatureAccessible(FtReaderFeatures.FEEDBACK, { session: this.session });
43
- }
44
- get canRateThisContent() {
45
- var _a;
46
- const canAccessRating = (_a = this.service) === null || _a === void 0 ? void 0 : _a.isFeatureAccessible(FtReaderFeatures.RATING, { session: this.session });
47
- return canAccessRating && this.ratingAllowed && this.configuredRatingType != FtRatingType.NO_RATING;
48
- }
49
- get configuredRatingType() {
50
- var _a, _b;
51
- return (_b = (_a = this.ratingSummary) === null || _a === void 0 ? void 0 : _a.type) !== null && _b !== void 0 ? _b : FtRatingType.NO_RATING;
52
- }
53
- get ratingTypeOfDoneRatingOfThisContent() {
54
- var _a, _b, _c;
55
- return (_c = (_b = (_a = this.ratingSummary) === null || _a === void 0 ? void 0 : _a.rating) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : FtRatingType.NO_RATING;
56
- }
57
- get ratingValue() {
58
- var _a, _b, _c;
59
- return (_c = (_b = (_a = this.ratingSummary) === null || _a === void 0 ? void 0 : _a.rating) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : -1;
60
- }
61
- get ratingDate() {
62
- var _a, _b;
63
- const date = (_b = (_a = this.ratingSummary) === null || _a === void 0 ? void 0 : _a.rating) === null || _b === void 0 ? void 0 : _b.date;
64
- return typeof date === "string" ? parseDate(date) : date;
65
- }
66
- render() {
67
- if (!this.canAccessFeedback && !this.canRateThisContent) {
68
- return nothing;
69
- }
70
- return html `
71
- <div class="ft-reader-feedback">
72
- ${this.hideTitle ? nothing : html `
73
- <ft-typography variant="title" part="main-title">
74
- ${this.i18n(this.i18nProperties.feedbackMainTitle)}
75
- </ft-typography>
76
- `}
77
- ${this.renderRatingSection()}
78
- ${this.renderFeedbackSection()}
79
- </div>
80
- `;
81
- }
82
- renderRatingSection() {
83
- if (this.canRateThisContent) {
84
- return html `
85
- <div class="ft-reader-feedback--rating" part="rating-container">
86
- <ft-typography variant="title-dense" part="section-title" class="ft-reader-feedback--section-title">
87
- ${this.i18n(this.ratingSummary.type === FtRatingType.DICHOTOMOUS
88
- ? this.i18nProperties.dichotomousRatingSectionTitle
89
- : this.i18nProperties.ratingSectionTitle)}
90
- </ft-typography>
91
- ${this.renderRating()}
92
- <ft-typography variant="caption" class="ft-reader-feedback--rating-date" part="rating-date">
93
- ${this.renderRatingDate()}
94
- </ft-typography>
95
- </div>
96
- `;
97
- }
98
- return nothing;
99
- }
100
- renderRatingDate() {
101
- const ratingDate = this.ratingDate;
102
- if (ratingDate == null) {
103
- return feedback.messages.notRated();
104
- }
105
- if (ratingDate.getTime() > (new Date().getTime() - 60000)) { // Less than 1 min ago
106
- return feedback.messages.ratedNow();
107
- }
108
- const today = new Date().toLocaleDateString();
109
- const formattedDate = ratingDate.toLocaleDateString();
110
- if (today === formattedDate) {
111
- return feedback.messages.ratedToday();
112
- }
113
- return feedback.messages.ratedOn(ratingDate);
114
- }
115
- renderRating() {
116
- switch (this.configuredRatingType) {
117
- case FtRatingType.STARS:
118
- return html `
119
- <div class="ft-reader-feedback--stars" part="rating rating-stars">
120
- ${repeat(new Array(5), (_, index) => index, (_, index) => {
121
- const active = this.ratingTypeOfDoneRatingOfThisContent === FtRatingType.STARS && this.ratingValue > index;
122
- const ratingValue = index + 1;
123
- return html `
124
- <ft-button round part="rating-stars-${ratingValue}"
125
- label="${feedback.messages.starsRating(ratingValue)}"
126
- tooltipPosition="top"
127
- .iconVariant=${this.iconVariant}
128
- icon="${active ? this.filledStarIcon : this.emptyStarIcon}"
129
- class="ft-reader-feedback--${active ? "active" : "inactive"}"
130
- @click=${() => this.rate(this.ratingValue === ratingValue ? undefined : ratingValue)}
131
- ></ft-button>
132
- `;
133
- })}
134
- </div>
135
- `;
136
- case FtRatingType.LIKE:
137
- const disliked = this.ratingTypeOfDoneRatingOfThisContent === FtRatingType.LIKE && this.ratingValue === 0;
138
- const liked = this.ratingTypeOfDoneRatingOfThisContent === FtRatingType.LIKE && this.ratingValue === 1;
139
- return html `
140
- <ft-switch unselectable
141
- @change=${(e) => this.rate(e.detail)}
142
- part="rating rating-like"
143
- label="${this.i18n(this.i18nProperties.ratingSectionTitle)}">
144
- <ft-switch-option .value=${1}
145
- ?selected=${liked}
146
- .iconVariant=${this.iconVariant}
147
- icon="${liked ? this.filledLikeIcon : this.emptyLikeIcon}"
148
- role="radio">
149
- ${feedback.messages.like()}
150
- </ft-switch-option>
151
- <ft-switch-option .value=${0}
152
- ?selected=${disliked}
153
- .iconVariant=${this.iconVariant}
154
- icon="${disliked ? this.filledDislikeIcon : this.emptyDislikeIcon}"
155
- role="radio">
156
- ${feedback.messages.dislike()}
157
- </ft-switch-option>
158
- </ft-switch>
159
- `;
160
- case FtRatingType.DICHOTOMOUS:
161
- const no = this.ratingTypeOfDoneRatingOfThisContent === FtRatingType.DICHOTOMOUS && this.ratingValue === 0;
162
- const yes = this.ratingTypeOfDoneRatingOfThisContent === FtRatingType.DICHOTOMOUS && this.ratingValue === 1;
163
- return html `
164
- <ft-switch unselectable
165
- @change=${(e) => this.rate(e.detail)}
166
- part="rating rating-dichotomous">
167
- <ft-switch-option .value=${1}
168
- ?selected=${yes}>
169
- ${feedback.messages.dichotomousYes()}
170
- </ft-switch-option>
171
- <ft-switch-option .value=${0}
172
- ?selected=${no}>
173
- ${feedback.messages.dichotomousNo()}
174
- </ft-switch-option>
175
- </ft-switch>
176
- `;
177
- }
178
- return nothing;
179
- }
180
- rate(value) {
181
- if ((value !== null && value !== void 0 ? value : -1) !== this.ratingValue) {
182
- this.dispatchEvent(new CustomEvent("rate", { detail: value }));
183
- }
184
- }
185
- renderFeedbackSection() {
186
- var _a, _b, _c, _d, _e;
187
- if (this.canAccessFeedback) {
188
- const mailLink = this.feedbackMailLinkBuilder(this.feedbackMessage);
189
- let submitButton = html `
190
- <ft-button primary
191
- type="submit" name="submit"
192
- class="ft-reader-feedback--send-feedback"
193
- ?disabled=${!this.feedbackMessage || !this.validFromEmail()}
194
- part="send-feedback">
195
- ${feedback.messages.okButton()}
196
- </ft-button>
197
- `;
198
- if (mailLink) {
199
- submitButton = html `
200
- <a class="ft-reader-feedback--feedback-link" href="${mailLink}">
201
- ${submitButton}
202
- </a>
203
- `;
204
- }
205
- const moreOptionsButton = this.withMoreOptionsButton && (((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.mailsSentByFluidTopics) || ((_b = this.configuration) === null || _b === void 0 ? void 0 : _b.mailsSentByFluidTopicsForUnauthenticatedUsers))
206
- ? html `
207
- <ft-button outlined
208
- type="button" name="more-options"
209
- class="ft-reader-feedback--more-options"
210
- @click=${this.onOpenMoreDetails}
211
- part="more-options">
212
- ${feedback.messages.moreOptionsButton()}
213
- </ft-button>
214
- `
215
- : nothing;
216
- return html `
217
- <form class="ft-reader-feedback--feedback" part="feedback-container" autocomplete="on"
218
- @submit=${(e) => this.onFormSubmitEvent(e, !!mailLink)}>
219
- <ft-typography variant="title-dense" part="section-title" class="ft-reader-feedback--section-title">
220
- ${this.i18n(this.i18nProperties.feedbackSectionTitle)}
221
- </ft-typography>
222
- ${((_d = (_c = this.session) === null || _c === void 0 ? void 0 : _c.profile) === null || _d === void 0 ? void 0 : _d.userId) == null && ((_e = this.configuration) === null || _e === void 0 ? void 0 : _e.mailsSentByFluidTopicsForUnauthenticatedUsers) ? html `
223
- <ft-text-field outlined name="email" type="email" autocomplete="email"
224
- class="ft-reader-feedback--from-input"
225
- label="${feedback.messages.feedbackfromEmail()}"
226
- @change=${(e) => this.from = e.detail.trim()}
227
- ?error=${this.from && !this.validFromEmail()}
228
- helper="${this.from && !this.validFromEmail() ? feedback.messages.feedbackfromEmailInvalid() : ""}"
229
- />
230
- ` : nothing}
231
- <ft-text-area outlined
232
- class="ft-reader-feedback--feedback-input" part="feedback-input"
233
- label="${feedback.messages.feedbackInputLabel()}"
234
- @live-change=${(e) => this.feedbackMessage = e.detail.trim()}
235
- ></ft-text-area>
236
- <div part="buttons-container">
237
- ${moreOptionsButton}
238
- ${submitButton}
239
- </div>
240
- </form>
241
- `;
242
- }
243
- return nothing;
244
- }
245
- onFormSubmitEvent(event, isUsingMailLink) {
246
- event.preventDefault();
247
- if (isUsingMailLink) {
248
- this.onMailerFeedbackSent();
249
- }
250
- else {
251
- this.sendFeedback();
252
- }
253
- }
254
- validFromEmail() {
255
- var _a, _b, _c;
256
- const expression = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$/;
257
- return !(((_b = (_a = this.session) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.userId) == null && ((_c = this.configuration) === null || _c === void 0 ? void 0 : _c.mailsSentByFluidTopicsForUnauthenticatedUsers))
258
- || expression.test(this.from);
259
- }
260
- sendFeedback() {
261
- var _a;
262
- this.dispatchEvent(new SendFeedbackEvent({
263
- message: this.feedbackInput.value,
264
- ...(((_a = this.configuration) === null || _a === void 0 ? void 0 : _a.mailsSentByFluidTopicsForUnauthenticatedUsers) && { from: this.from }),
265
- }));
266
- }
267
- onMailerFeedbackSent() {
268
- this.dispatchEvent(new CustomEvent("mailer-feedback"));
269
- }
270
- onOpenMoreDetails() {
271
- this.dispatchEvent(new CustomEvent("open-more-options"));
272
- }
273
- clearFeedbackInput() {
274
- setTimeout(() => this.feedbackInput.setValue("", true), 0);
275
- }
1
+ import { FtBaseFeedback } from "./ft-base-feedback";
2
+ import { generateFeedbackStyles } from "./ft-base-feedback.styles";
3
+ import { FtReaderFeedbackCssVariables } from "./ft-reader-feedback.styles";
4
+ export class FtReaderFeedback extends FtBaseFeedback {
276
5
  }
277
- FtReaderFeedback.elementDefinitions = {
278
- "ft-button": FtButton,
279
- "ft-typography": FtTypography,
280
- "ft-switch": FtSwitch,
281
- "ft-switch-option": FtSwitchOption,
282
- "ft-text-area": FtTextArea,
283
- "ft-text-field": FtTextField,
284
- };
285
- FtReaderFeedback.styles = styles;
286
- __decorate([
287
- property({ type: Boolean })
288
- ], FtReaderFeedback.prototype, "editorMode", void 0);
289
- __decorate([
290
- property({ type: Boolean })
291
- ], FtReaderFeedback.prototype, "hideTitle", void 0);
292
- __decorate([
293
- property({ type: Boolean })
294
- ], FtReaderFeedback.prototype, "withMoreOptionsButton", void 0);
295
- __decorate([
296
- property({ type: Boolean })
297
- ], FtReaderFeedback.prototype, "ratingAllowed", void 0);
298
- __decorate([
299
- property({ attribute: false })
300
- ], FtReaderFeedback.prototype, "i18nProperties", void 0);
301
- __decorate([
302
- property({ attribute: false })
303
- ], FtReaderFeedback.prototype, "ratingSummary", void 0);
304
- __decorate([
305
- property({ attribute: false })
306
- ], FtReaderFeedback.prototype, "session", void 0);
307
- __decorate([
308
- query(".ft-reader-feedback--feedback-input")
309
- ], FtReaderFeedback.prototype, "feedbackInput", void 0);
310
- __decorate([
311
- state()
312
- ], FtReaderFeedback.prototype, "from", void 0);
313
- __decorate([
314
- state()
315
- ], FtReaderFeedback.prototype, "feedbackMessage", void 0);
316
- __decorate([
317
- property()
318
- ], FtReaderFeedback.prototype, "iconVariant", void 0);
319
- __decorate([
320
- property()
321
- ], FtReaderFeedback.prototype, "emptyStarIcon", void 0);
322
- __decorate([
323
- property()
324
- ], FtReaderFeedback.prototype, "filledStarIcon", void 0);
325
- __decorate([
326
- property()
327
- ], FtReaderFeedback.prototype, "emptyLikeIcon", void 0);
328
- __decorate([
329
- property()
330
- ], FtReaderFeedback.prototype, "filledLikeIcon", void 0);
331
- __decorate([
332
- property()
333
- ], FtReaderFeedback.prototype, "emptyDislikeIcon", void 0);
334
- __decorate([
335
- property()
336
- ], FtReaderFeedback.prototype, "filledDislikeIcon", void 0);
337
- __decorate([
338
- redux({
339
- store: "reader",
340
- selector: (state) => { var _a; return (_a = state.configuration) === null || _a === void 0 ? void 0 : _a.feedback; },
341
- })
342
- ], FtReaderFeedback.prototype, "configuration", void 0);
343
- __decorate([
344
- property()
345
- ], FtReaderFeedback.prototype, "feedbackMailLinkBuilder", void 0);
6
+ FtReaderFeedback.styles = generateFeedbackStyles(FtReaderFeedbackCssVariables);