@internetarchive/ia-book-actions 0.0.6-4 → 0.0.6-8
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/demo/index.html +11 -1
- package/package.json +2 -1
- package/src/assets/styles/collapsible-action-group.js +3 -0
- package/src/components/collapsible-action-group.js +25 -0
- package/src/components/dialog-alert.js +139 -0
- package/src/core/services/actions-handler/actions-handler-service.js +14 -6
- package/src/core/services/actions-handler/actions-handler.js +47 -31
- package/src/ia-book-actions.js +69 -16
- package/test/ia-book-actions.test.js +59 -0
package/demo/index.html
CHANGED
|
@@ -71,6 +71,16 @@
|
|
|
71
71
|
float: left;
|
|
72
72
|
margin: 2px;
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
#ui-overlay {
|
|
76
|
+
position: fixed;
|
|
77
|
+
top: 0;
|
|
78
|
+
left: 0;
|
|
79
|
+
width: 100%;
|
|
80
|
+
height: 100%;
|
|
81
|
+
background: black;
|
|
82
|
+
opacity: 0.3;
|
|
83
|
+
}
|
|
74
84
|
</style>
|
|
75
85
|
</head>
|
|
76
86
|
|
|
@@ -146,7 +156,7 @@
|
|
|
146
156
|
if (e.target.value === 'user_has_browsed') {
|
|
147
157
|
lendingStatus1.user_has_browsed = true;
|
|
148
158
|
lendingStatus1.available_to_browse = false;
|
|
149
|
-
lendingStatus1.secondsLeftOnLoan =
|
|
159
|
+
lendingStatus1.secondsLeftOnLoan = 30;
|
|
150
160
|
lendingStatus1.browsingExpired = false;
|
|
151
161
|
} else if(e.target.value === 'browsingExpired') {
|
|
152
162
|
lendingStatus1.user_has_browsed = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@internetarchive/ia-book-actions",
|
|
3
|
-
"version": "0.0.6-
|
|
3
|
+
"version": "0.0.6-8",
|
|
4
4
|
"description": "Bookreader actions for borrowable book",
|
|
5
5
|
"author": "Internet Archive",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"@internetarchive/ia-icons": "^1.2.2",
|
|
22
22
|
"@internetarchive/icon-bookmark": "^1.1.3",
|
|
23
23
|
"@internetarchive/icon-info": "^1.2.6",
|
|
24
|
+
"@internetarchive/icon-close": "^1.1.3",
|
|
24
25
|
"@internetarchive/shared-resize-observer": "^0.0.1",
|
|
25
26
|
"lit-element": "^2.4.0",
|
|
26
27
|
"lit-html": "^1.3.0"
|
|
@@ -27,6 +27,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
27
27
|
hasAdminAccess: { type: Boolean },
|
|
28
28
|
dropdownArrow: { type: String },
|
|
29
29
|
disabled: { type: Boolean },
|
|
30
|
+
bookHasBrowsed: { type: Boolean },
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -45,6 +46,13 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
45
46
|
this.title = '';
|
|
46
47
|
this.loaderIcon = 'https://archive.org/upload/images/tree/loading.gif';
|
|
47
48
|
this.disabled = false;
|
|
49
|
+
this.bookHasBrowsed = false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
firstUpdated() {
|
|
53
|
+
if (this.bookHasBrowsed) {
|
|
54
|
+
this.emitFetchLoanToken();
|
|
55
|
+
}
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
updated(changed) {
|
|
@@ -53,6 +61,23 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
53
61
|
this.resetActions();
|
|
54
62
|
}
|
|
55
63
|
}
|
|
64
|
+
|
|
65
|
+
// this is execute on demo page only
|
|
66
|
+
if (changed.has('bookHasBrowsed')) {
|
|
67
|
+
this.emitFetchLoanToken();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* emit custom event to fetch loan token */
|
|
72
|
+
emitFetchLoanToken() {
|
|
73
|
+
this.dispatchEvent(
|
|
74
|
+
new CustomEvent('fetchLoanToken', {
|
|
75
|
+
detail: {
|
|
76
|
+
event: { category: 'action' },
|
|
77
|
+
bookHasBrowsed: this.bookHasBrowsed,
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
|
+
);
|
|
56
81
|
}
|
|
57
82
|
|
|
58
83
|
/**
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
import { LitElement, html, css } from 'lit-element';
|
|
3
|
+
import { classMap } from 'lit-html/directives/class-map';
|
|
4
|
+
|
|
5
|
+
import '@internetarchive/icon-close/icon-close.js';
|
|
6
|
+
import buttonBaseStyle from '../assets/styles/ia-button.js';
|
|
7
|
+
|
|
8
|
+
export class ShowDialog extends LitElement {
|
|
9
|
+
static get properties() {
|
|
10
|
+
return {
|
|
11
|
+
title: { type: String },
|
|
12
|
+
body: { type: String },
|
|
13
|
+
actions: { type: Array },
|
|
14
|
+
opened: { type: Boolean },
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.title = 'Error';
|
|
21
|
+
this.body =
|
|
22
|
+
'Unexpected error: loan does not exist. Please try deleting your archive.org cookie.';
|
|
23
|
+
this.actions = [];
|
|
24
|
+
this.opened = false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
updated(changed) {
|
|
28
|
+
if (changed.get('opened') === false) {
|
|
29
|
+
this.addOverlay();
|
|
30
|
+
} else {
|
|
31
|
+
this.removeOverlay();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
render() {
|
|
36
|
+
return html`
|
|
37
|
+
<div
|
|
38
|
+
class="${classMap({
|
|
39
|
+
dialog: true,
|
|
40
|
+
opened: this.opened,
|
|
41
|
+
closed: !this.opened,
|
|
42
|
+
})}"
|
|
43
|
+
>
|
|
44
|
+
<div class="dialog-head">
|
|
45
|
+
${this.title}
|
|
46
|
+
<ia-icon-close
|
|
47
|
+
@click="${() =>
|
|
48
|
+
this.dispatchEvent(new CustomEvent('dialogAlertClose'))}"
|
|
49
|
+
></ia-icon-close>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="dialog-body">${this.body}</div>
|
|
52
|
+
<div class="dialog-foot">${this.renderActionButton}</div>
|
|
53
|
+
</div>
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* exceptional case to use dom element */
|
|
58
|
+
addOverlay() {
|
|
59
|
+
if (this.opened && !document.getElementById('ui-overlay')) {
|
|
60
|
+
const overlayElement = document.createElement('div');
|
|
61
|
+
overlayElement.id = 'ui-overlay';
|
|
62
|
+
document.getElementsByTagName('body')[0].appendChild(overlayElement);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* exceptional case to use dom element */
|
|
67
|
+
removeOverlay() {
|
|
68
|
+
const overlayElement = document.getElementById('ui-overlay');
|
|
69
|
+
if (overlayElement) overlayElement.remove();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
get renderActionButton() {
|
|
73
|
+
if (!this.actions) return;
|
|
74
|
+
|
|
75
|
+
return this.actions.map(
|
|
76
|
+
action =>
|
|
77
|
+
html`<a class=${action.className} href=${action.href}>
|
|
78
|
+
${action.text}
|
|
79
|
+
</button>`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static get styles() {
|
|
84
|
+
const dialogStyle = css`
|
|
85
|
+
:host {
|
|
86
|
+
color: #343434;
|
|
87
|
+
font-size: 1.6rem;
|
|
88
|
+
}
|
|
89
|
+
.dialog {
|
|
90
|
+
position: absolute;
|
|
91
|
+
background: #fff;
|
|
92
|
+
border-radius: 1.2rem;
|
|
93
|
+
z-index: 3000;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
min-width: 300px;
|
|
96
|
+
max-width: 400px;
|
|
97
|
+
left: 50%;
|
|
98
|
+
transform: translateX(-50%);
|
|
99
|
+
|
|
100
|
+
border: 2px solid #ccc;
|
|
101
|
+
border-radius: 12px;
|
|
102
|
+
box-shadow: 0px 0px 27px 6px rgb(66 66 66 / 80%);
|
|
103
|
+
}
|
|
104
|
+
.dialog-head,
|
|
105
|
+
.dialog-body,
|
|
106
|
+
.dialog-foot {
|
|
107
|
+
padding: 1rem;
|
|
108
|
+
user-select: none;
|
|
109
|
+
text-align: left;
|
|
110
|
+
}
|
|
111
|
+
.dialog-body {
|
|
112
|
+
border: 1px solid #d8d8d8;
|
|
113
|
+
}
|
|
114
|
+
ia-icon-close {
|
|
115
|
+
position: absolute;
|
|
116
|
+
right: 0.5rem;
|
|
117
|
+
top: 0.5rem;
|
|
118
|
+
width: 2.5rem;
|
|
119
|
+
height: 2.5rem;
|
|
120
|
+
vertical-align: middle;
|
|
121
|
+
--iconFillColor: #333;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
}
|
|
124
|
+
.opened {
|
|
125
|
+
display: flex;
|
|
126
|
+
}
|
|
127
|
+
.closed {
|
|
128
|
+
display: none;
|
|
129
|
+
}
|
|
130
|
+
a {
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
}
|
|
133
|
+
`;
|
|
134
|
+
|
|
135
|
+
return [buttonBaseStyle, dialogStyle];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
customElements.define('show-dialog', ShowDialog);
|
|
@@ -8,17 +8,14 @@ export default function ActionsHandlerService(options) {
|
|
|
8
8
|
const option = {
|
|
9
9
|
action: null,
|
|
10
10
|
identifier: '',
|
|
11
|
-
data: {},
|
|
12
11
|
success() {},
|
|
13
12
|
error() {},
|
|
14
|
-
loader: true,
|
|
15
|
-
type: 'POST',
|
|
16
13
|
...options,
|
|
17
14
|
};
|
|
18
15
|
|
|
19
16
|
let baseHost = '';
|
|
20
17
|
if (window.location.pathname === '/demo/') {
|
|
21
|
-
baseHost = `/demo
|
|
18
|
+
baseHost = `/demo/`;
|
|
22
19
|
} else {
|
|
23
20
|
baseHost = `/services/loans/loan`;
|
|
24
21
|
}
|
|
@@ -32,8 +29,20 @@ export default function ActionsHandlerService(options) {
|
|
|
32
29
|
body: formData,
|
|
33
30
|
})
|
|
34
31
|
.then(response => {
|
|
32
|
+
// test changes, (won't affect you)
|
|
35
33
|
if (baseHost == '/demo/1' || baseHost == '/demo/') {
|
|
36
|
-
|
|
34
|
+
if (option.action == 'create_token') {
|
|
35
|
+
// return {'success': false, 'error': 'loan token not found. please try again later.',};
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
token: '1640945898-f77a0cb615190798f1faf2dafe277b2e',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
error:
|
|
44
|
+
'This book is not available to borrow at this time. Please try again later.',
|
|
45
|
+
};
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
// The response is a Response instance.
|
|
@@ -42,7 +51,6 @@ export default function ActionsHandlerService(options) {
|
|
|
42
51
|
})
|
|
43
52
|
.then(data => {
|
|
44
53
|
// `data` is the parsed version of the JSON returned from the above endpoint.
|
|
45
|
-
console.log('actual reponse for endpoint', data);
|
|
46
54
|
if (!data.error) {
|
|
47
55
|
option?.success(data);
|
|
48
56
|
} else {
|
|
@@ -15,6 +15,8 @@ export default class ActionsHandler extends LitElement {
|
|
|
15
15
|
super();
|
|
16
16
|
this.identifier = identifier;
|
|
17
17
|
this.ajaxTimeout = 6000;
|
|
18
|
+
this.loanTokenPollingDelay = 20000; // 20000 ms = 20 sec
|
|
19
|
+
this.loanTokenInterval = null;
|
|
18
20
|
this.bindEvents();
|
|
19
21
|
}
|
|
20
22
|
|
|
@@ -84,11 +86,27 @@ export default class ActionsHandler extends LitElement {
|
|
|
84
86
|
const { category, action } = detail.event;
|
|
85
87
|
this.sendEvent(category, action);
|
|
86
88
|
});
|
|
89
|
+
|
|
90
|
+
this.addEventListener('fetchLoanToken', ({ detail }) => {
|
|
91
|
+
const bookHasBrowsed = detail?.bookHasBrowsed;
|
|
92
|
+
|
|
93
|
+
// fetch loan token and set an interval
|
|
94
|
+
if (bookHasBrowsed) {
|
|
95
|
+
console.log('token poll started...');
|
|
96
|
+
|
|
97
|
+
this.loanTokenInterval = setInterval(() => {
|
|
98
|
+
this.handleLoanTokenPoller();
|
|
99
|
+
}, this.loanTokenPollingDelay);
|
|
100
|
+
} else {
|
|
101
|
+
// if book is not browsed, just clear token polling interval
|
|
102
|
+
clearInterval(this.loanTokenInterval);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
87
105
|
}
|
|
88
106
|
|
|
89
107
|
handleBrowseIt() {
|
|
90
108
|
const context = 'browse_book';
|
|
91
|
-
this.
|
|
109
|
+
this.ActionError(context);
|
|
92
110
|
|
|
93
111
|
ActionsHandlerService({
|
|
94
112
|
action: context,
|
|
@@ -97,16 +115,14 @@ export default class ActionsHandler extends LitElement {
|
|
|
97
115
|
this.handleReadItNow();
|
|
98
116
|
},
|
|
99
117
|
error: data => {
|
|
100
|
-
|
|
101
|
-
alert(data.error);
|
|
102
|
-
this.toggleActionBarState(context, data);
|
|
118
|
+
this.ActionError(context, data);
|
|
103
119
|
},
|
|
104
120
|
});
|
|
105
121
|
}
|
|
106
122
|
|
|
107
123
|
handleReturnIt() {
|
|
108
124
|
const context = 'return_loan';
|
|
109
|
-
this.
|
|
125
|
+
this.ActionError(context);
|
|
110
126
|
|
|
111
127
|
ActionsHandlerService({
|
|
112
128
|
action: context,
|
|
@@ -116,16 +132,14 @@ export default class ActionsHandler extends LitElement {
|
|
|
116
132
|
URLHelper.goToUrl(`/details/${this.identifier}`, true);
|
|
117
133
|
},
|
|
118
134
|
error: data => {
|
|
119
|
-
|
|
120
|
-
alert(data.error);
|
|
121
|
-
this.toggleActionBarState(context);
|
|
135
|
+
this.ActionError(context, data);
|
|
122
136
|
},
|
|
123
137
|
});
|
|
124
138
|
}
|
|
125
139
|
|
|
126
140
|
handleBorrowIt() {
|
|
127
141
|
const context = 'borrow_book';
|
|
128
|
-
this.
|
|
142
|
+
this.ActionError(context);
|
|
129
143
|
|
|
130
144
|
ActionsHandlerService({
|
|
131
145
|
action: context,
|
|
@@ -134,16 +148,14 @@ export default class ActionsHandler extends LitElement {
|
|
|
134
148
|
this.handleReadItNow();
|
|
135
149
|
},
|
|
136
150
|
error: data => {
|
|
137
|
-
|
|
138
|
-
alert(data.error);
|
|
139
|
-
this.toggleActionBarState(context, data);
|
|
151
|
+
this.ActionError(context, data);
|
|
140
152
|
},
|
|
141
153
|
});
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
handleReserveIt() {
|
|
145
157
|
const context = 'join_waitlist';
|
|
146
|
-
this.
|
|
158
|
+
this.ActionError(context);
|
|
147
159
|
|
|
148
160
|
ActionsHandlerService({
|
|
149
161
|
action: context,
|
|
@@ -152,16 +164,14 @@ export default class ActionsHandler extends LitElement {
|
|
|
152
164
|
URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
|
|
153
165
|
},
|
|
154
166
|
error: data => {
|
|
155
|
-
|
|
156
|
-
alert(data.error);
|
|
157
|
-
this.toggleActionBarState(context);
|
|
167
|
+
this.ActionError(context, data);
|
|
158
168
|
},
|
|
159
169
|
});
|
|
160
170
|
}
|
|
161
171
|
|
|
162
172
|
handleRemoveFromWaitingList() {
|
|
163
173
|
const context = 'leave_waitlist';
|
|
164
|
-
this.
|
|
174
|
+
this.ActionError(context);
|
|
165
175
|
|
|
166
176
|
ActionsHandlerService({
|
|
167
177
|
action: context,
|
|
@@ -170,13 +180,30 @@ export default class ActionsHandler extends LitElement {
|
|
|
170
180
|
URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
|
|
171
181
|
},
|
|
172
182
|
error: data => {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
183
|
+
this.ActionError(context, data);
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
handleLoanTokenPoller() {
|
|
189
|
+
const context = 'create_token';
|
|
190
|
+
ActionsHandlerService({
|
|
191
|
+
identifier: this.identifier,
|
|
192
|
+
action: context,
|
|
193
|
+
error: data => {
|
|
194
|
+
this.ActionError(context, data);
|
|
176
195
|
},
|
|
177
196
|
});
|
|
178
197
|
}
|
|
179
198
|
|
|
199
|
+
ActionError(context, data = {}) {
|
|
200
|
+
this.dispatchEvent(
|
|
201
|
+
new CustomEvent('lendingActionError', {
|
|
202
|
+
detail: { context, data },
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
180
207
|
handleLoginOk() {
|
|
181
208
|
/* eslint class-methods-use-this: "off" */
|
|
182
209
|
const target = `/account/login?referer=${encodeURIComponent(
|
|
@@ -188,9 +215,6 @@ export default class ActionsHandler extends LitElement {
|
|
|
188
215
|
handleReadItNow(extraParam) {
|
|
189
216
|
const currentParams = new URLSearchParams(window.location.search);
|
|
190
217
|
|
|
191
|
-
// Delete the ?q= parameter just after borrow a book. see: WEBDEV-3979
|
|
192
|
-
currentParams.delete('q');
|
|
193
|
-
|
|
194
218
|
if (extraParam) {
|
|
195
219
|
// append extraParam key-value in currentParams
|
|
196
220
|
const extraParams = new URLSearchParams(extraParam);
|
|
@@ -226,12 +250,4 @@ export default class ActionsHandler extends LitElement {
|
|
|
226
250
|
cookie += '; path=/; domain=.archive.org;';
|
|
227
251
|
document.cookie = cookie;
|
|
228
252
|
}
|
|
229
|
-
|
|
230
|
-
toggleActionBarState(context, data = {}) {
|
|
231
|
-
this.dispatchEvent(
|
|
232
|
-
new CustomEvent('toggle-action-bar-state', {
|
|
233
|
-
detail: { context, data }
|
|
234
|
-
})
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
253
|
}
|
package/src/ia-book-actions.js
CHANGED
|
@@ -7,6 +7,7 @@ import './components/collapsible-action-group.js';
|
|
|
7
7
|
import './components/book-title-bar.js';
|
|
8
8
|
import './components/text-group.js';
|
|
9
9
|
import './components/info-icon.js';
|
|
10
|
+
import './components/dialog-alert.js';
|
|
10
11
|
|
|
11
12
|
import GetLendingActions from './core/services/get-lending-actions.js';
|
|
12
13
|
import { mobileContainerWidth } from './core/config/constants.js';
|
|
@@ -23,6 +24,8 @@ export default class IABookActions extends LitElement {
|
|
|
23
24
|
barType: { type: String },
|
|
24
25
|
sharedObserver: { attribute: false },
|
|
25
26
|
disable: { type: Boolean },
|
|
27
|
+
dialogVisible: { type: Boolean },
|
|
28
|
+
bookHasBrowsed: { type: Boolean },
|
|
26
29
|
};
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -41,7 +44,9 @@ export default class IABookActions extends LitElement {
|
|
|
41
44
|
this.primaryColor = 'primary';
|
|
42
45
|
this.secondaryActions = [];
|
|
43
46
|
this.lendingOptions = {};
|
|
44
|
-
this.
|
|
47
|
+
this.disableActionGroup = false;
|
|
48
|
+
this.dialogVisible = false;
|
|
49
|
+
this.bookHasBrowsed = false;
|
|
45
50
|
}
|
|
46
51
|
|
|
47
52
|
disconnectedCallback() {
|
|
@@ -141,10 +146,12 @@ export default class IABookActions extends LitElement {
|
|
|
141
146
|
return action != null;
|
|
142
147
|
});
|
|
143
148
|
|
|
144
|
-
|
|
149
|
+
this.bookHasBrowsed =
|
|
145
150
|
this.lendingStatus.user_has_browsed &&
|
|
146
|
-
!this.lendingStatus.
|
|
147
|
-
) {
|
|
151
|
+
!this.lendingStatus.browsingExpired;
|
|
152
|
+
if (this.bookHasBrowsed) {
|
|
153
|
+
// start timer for 1-hour borrowed book.
|
|
154
|
+
// when 1 hour is completed, we shows browse-again button
|
|
148
155
|
this.startBrowseTimer();
|
|
149
156
|
}
|
|
150
157
|
}
|
|
@@ -154,9 +161,21 @@ export default class IABookActions extends LitElement {
|
|
|
154
161
|
<section class="lending-wrapper">
|
|
155
162
|
${this.barType === 'title' ? this.bookTitleBar : this.bookActionBar}
|
|
156
163
|
</section>
|
|
164
|
+
|
|
165
|
+
<show-dialog
|
|
166
|
+
.title=${this.dialogTitle}
|
|
167
|
+
.body=${this.dialogBody}
|
|
168
|
+
.actions=${this.dialogActions}
|
|
169
|
+
?opened="${this.dialogVisible}"
|
|
170
|
+
@dialogAlertClose="${() => this.closeDialogAlert()}"
|
|
171
|
+
></show-dialog>
|
|
157
172
|
`;
|
|
158
173
|
}
|
|
159
174
|
|
|
175
|
+
closeDialogAlert() {
|
|
176
|
+
this.dialogVisible = false;
|
|
177
|
+
}
|
|
178
|
+
|
|
160
179
|
get bookTitleBar() {
|
|
161
180
|
return html`<book-title-bar
|
|
162
181
|
.identifier=${this.identifier}
|
|
@@ -174,27 +193,61 @@ export default class IABookActions extends LitElement {
|
|
|
174
193
|
.secondaryActions=${this.secondaryActions}
|
|
175
194
|
.width=${this.width}
|
|
176
195
|
.hasAdminAccess=${this.hasAdminAccess}
|
|
177
|
-
.disabled=${this.
|
|
178
|
-
|
|
196
|
+
.disabled=${this.disableActionGroup}
|
|
197
|
+
.bookHasBrowsed=${this.bookHasBrowsed}
|
|
198
|
+
@lendingActionError=${this.handleLendingActionError}
|
|
179
199
|
>
|
|
180
200
|
</collapsible-action-group>
|
|
181
201
|
${this.textGroupTemplate} ${this.infoIconTemplate}
|
|
182
202
|
`;
|
|
183
203
|
}
|
|
184
204
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
205
|
+
handleLendingActionError(e) {
|
|
206
|
+
// toggle activity loader
|
|
207
|
+
this.disableActionGroup = !this.disableActionGroup;
|
|
208
|
+
|
|
209
|
+
const context = e?.detail?.context;
|
|
210
|
+
const errorMsg = e?.detail?.data?.error;
|
|
211
|
+
|
|
212
|
+
// early exist if you don't have errorMsg
|
|
213
|
+
if (!errorMsg) return;
|
|
214
|
+
|
|
215
|
+
this.initializeDialogAlert(context, errorMsg);
|
|
216
|
+
|
|
217
|
+
// update action bar state if book is not available to browse or borrow.
|
|
218
|
+
if (errorMsg && errorMsg.match(/not available to borrow/gm)) {
|
|
219
|
+
let currStatus = this.lendingStatus;
|
|
220
|
+
if (context === 'browse_book') {
|
|
221
|
+
currStatus = {
|
|
222
|
+
...this.lendingStatus,
|
|
223
|
+
available_to_browse: false,
|
|
224
|
+
};
|
|
225
|
+
} else if (context === 'borrow_book') {
|
|
226
|
+
currStatus = {
|
|
227
|
+
...this.lendingStatus,
|
|
228
|
+
available_to_borrow: false,
|
|
229
|
+
};
|
|
194
230
|
}
|
|
231
|
+
this.lendingStatus = currStatus;
|
|
195
232
|
}
|
|
233
|
+
}
|
|
196
234
|
|
|
197
|
-
|
|
235
|
+
/* set props value to show dialog alert */
|
|
236
|
+
initializeDialogAlert(context, errorMsg) {
|
|
237
|
+
this.dialogVisible = true;
|
|
238
|
+
this.dialogTitle = 'Sorry!';
|
|
239
|
+
this.dialogBody = errorMsg;
|
|
240
|
+
this.dialogActions = [];
|
|
241
|
+
|
|
242
|
+
if (context === 'create_token') {
|
|
243
|
+
this.dialogActions = [
|
|
244
|
+
{
|
|
245
|
+
className: 'ia-button primary',
|
|
246
|
+
text: 'Back to Item Details',
|
|
247
|
+
href: `/details/${this.lendingStatus.bookUrl}`,
|
|
248
|
+
},
|
|
249
|
+
];
|
|
250
|
+
}
|
|
198
251
|
}
|
|
199
252
|
|
|
200
253
|
get iconClass() {
|
|
@@ -106,6 +106,65 @@ describe('Primary Actions data', () => {
|
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
describe('Borrow status actions', () => {
|
|
109
|
+
it('Update available_to_browse key when book is not available to borrow', async () => {
|
|
110
|
+
const el = await fixture(
|
|
111
|
+
container({
|
|
112
|
+
userid: '@user1',
|
|
113
|
+
lendingStatus: {
|
|
114
|
+
is_lendable: true,
|
|
115
|
+
available_to_browse: true,
|
|
116
|
+
available_to_borrow: true,
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const errorEvent = new CustomEvent('lendingActionError');
|
|
122
|
+
el.addEventListener('lendingActionError', () => {
|
|
123
|
+
el.handleLendingActionError({
|
|
124
|
+
detail: {
|
|
125
|
+
context: 'browse_book',
|
|
126
|
+
data: { error: 'not available to borrow' },
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
el.dispatchEvent(errorEvent);
|
|
131
|
+
await el.updateComplete;
|
|
132
|
+
|
|
133
|
+
console.log(el.lendingStatus);
|
|
134
|
+
// removed available_to_browse from lending bar
|
|
135
|
+
expect(el.lendingStatus.available_to_browse).to.be.false;
|
|
136
|
+
expect(el.primaryActions[0].text).to.equal('Borrow for 14 days');
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('Update available_to_borrow key when book is not available to borrow', async () => {
|
|
140
|
+
const el = await fixture(
|
|
141
|
+
container({
|
|
142
|
+
userid: '@user1',
|
|
143
|
+
lendingStatus: {
|
|
144
|
+
is_lendable: true,
|
|
145
|
+
available_to_browse: true,
|
|
146
|
+
available_to_borrow: true,
|
|
147
|
+
},
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const errorEvent = new Event('lendingActionError');
|
|
152
|
+
el.addEventListener('lendingActionError', () => {
|
|
153
|
+
el.handleLendingActionError({
|
|
154
|
+
detail: {
|
|
155
|
+
context: 'borrow_book',
|
|
156
|
+
data: { error: 'not available to borrow' },
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
el.dispatchEvent(errorEvent);
|
|
161
|
+
await el.updateComplete;
|
|
162
|
+
|
|
163
|
+
// removed available_to_borrow from lending bar
|
|
164
|
+
expect(el.lendingStatus.available_to_borrow).to.be.false;
|
|
165
|
+
expect(el.primaryActions[0].text).to.equal('Borrow for 1 hour');
|
|
166
|
+
});
|
|
167
|
+
|
|
109
168
|
it('Check action for borrowable book without user', async () => {
|
|
110
169
|
const el = await fixture(
|
|
111
170
|
container({
|