@internetarchive/ia-book-actions 0.0.6-1 → 0.0.6-5
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 +1 -1
- package/package.json +1 -1
- package/src/assets/styles/collapsible-action-group.js +7 -2
- package/src/components/collapsible-action-group.js +25 -8
- package/src/core/services/actions-handler/actions-handler-service.js +20 -22
- package/src/core/services/actions-handler/actions-handler.js +52 -9
- package/src/ia-book-actions.js +22 -2
- package/test/components/collapsible-action-group.test.js +16 -0
package/demo/index.html
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
iaBookActions.userid = '';
|
|
97
97
|
iaBookActions.identifier = identifier;
|
|
98
98
|
iaBookActions.bookTitle = 'Contemporary Black biography. Volume 39 : profiles from the interContemporary Black biography. Volume 39';
|
|
99
|
-
iaBookActions.lendingStatus =
|
|
99
|
+
iaBookActions.lendingStatus = canBrowseAndBorrow;
|
|
100
100
|
iaBookActions.bwbPurchaseUrl = '';
|
|
101
101
|
iaBookActions.barType = '';
|
|
102
102
|
|
package/package.json
CHANGED
|
@@ -80,7 +80,7 @@ export default css`
|
|
|
80
80
|
padding: 0 0.6rem;
|
|
81
81
|
margin-left: 0;
|
|
82
82
|
}
|
|
83
|
-
.
|
|
83
|
+
.actionloader {
|
|
84
84
|
vertical-align: middle;
|
|
85
85
|
visibility: hidden;
|
|
86
86
|
padding: 0.9rem 0.2rem;
|
|
@@ -129,9 +129,14 @@ export default css`
|
|
|
129
129
|
display: initial;
|
|
130
130
|
font-size: 1.4rem;
|
|
131
131
|
}
|
|
132
|
-
|
|
133
132
|
.unavailable {
|
|
134
133
|
opacity: 0.7;
|
|
135
134
|
pointer-events: none;
|
|
136
135
|
}
|
|
136
|
+
|
|
137
|
+
.disabled {
|
|
138
|
+
opacity: 0.8;
|
|
139
|
+
pointer-events: none;
|
|
140
|
+
visibility: visible;
|
|
141
|
+
}
|
|
137
142
|
`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { html } from 'lit-element';
|
|
2
2
|
import { nothing } from 'lit-html';
|
|
3
|
+
import { classMap } from 'lit-html/directives/class-map';
|
|
3
4
|
|
|
4
5
|
import ActionsHandler from '../core/services/actions-handler/actions-handler.js';
|
|
5
6
|
|
|
@@ -25,6 +26,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
25
26
|
width: { type: Number },
|
|
26
27
|
hasAdminAccess: { type: Boolean },
|
|
27
28
|
dropdownArrow: { type: String },
|
|
29
|
+
disabled: { type: Boolean },
|
|
28
30
|
};
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -42,6 +44,7 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
42
44
|
this.initialButton = false;
|
|
43
45
|
this.title = '';
|
|
44
46
|
this.loaderIcon = 'https://archive.org/upload/images/tree/loading.gif';
|
|
47
|
+
this.disabled = false;
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
updated(changed) {
|
|
@@ -94,13 +97,20 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
94
97
|
|
|
95
98
|
render() {
|
|
96
99
|
return html`
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
<div
|
|
101
|
+
class="${classMap({
|
|
102
|
+
actiongroup: true,
|
|
103
|
+
disabled: this.disabled,
|
|
104
|
+
})}"
|
|
105
|
+
>
|
|
106
|
+
${this.getLoaderIcon}
|
|
107
|
+
<section class="action-buttons primary">
|
|
108
|
+
${this.renderPrimaryActions}
|
|
109
|
+
</section>
|
|
110
|
+
<section class="action-buttons secondary">
|
|
111
|
+
${this.renderSecondaryActions}
|
|
112
|
+
</section>
|
|
113
|
+
</div>
|
|
104
114
|
`;
|
|
105
115
|
}
|
|
106
116
|
|
|
@@ -225,7 +235,14 @@ export class CollapsibleActionGroup extends ActionsHandler {
|
|
|
225
235
|
* @returns { HTMLElement }
|
|
226
236
|
*/
|
|
227
237
|
get getLoaderIcon() {
|
|
228
|
-
return html`<img
|
|
238
|
+
return html`<img
|
|
239
|
+
class="${classMap({
|
|
240
|
+
actionloader: true,
|
|
241
|
+
disabled: this.disabled,
|
|
242
|
+
})}"
|
|
243
|
+
alt=""
|
|
244
|
+
src="${this.loaderIcon}"
|
|
245
|
+
/>`;
|
|
229
246
|
}
|
|
230
247
|
|
|
231
248
|
/**
|
|
@@ -10,19 +10,15 @@ export default function ActionsHandlerService(options) {
|
|
|
10
10
|
identifier: '',
|
|
11
11
|
data: {},
|
|
12
12
|
success() {},
|
|
13
|
-
error
|
|
13
|
+
error() {},
|
|
14
14
|
loader: true,
|
|
15
15
|
type: 'POST',
|
|
16
16
|
...options,
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
if (option.loader) {
|
|
20
|
-
showActionButtonLoader();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
19
|
let baseHost = '';
|
|
24
20
|
if (window.location.pathname === '/demo/') {
|
|
25
|
-
baseHost = `/demo
|
|
21
|
+
baseHost = `/demo/1`;
|
|
26
22
|
} else {
|
|
27
23
|
baseHost = `/services/loans/loan`;
|
|
28
24
|
}
|
|
@@ -36,23 +32,25 @@ export default function ActionsHandlerService(options) {
|
|
|
36
32
|
body: formData,
|
|
37
33
|
})
|
|
38
34
|
.then(response => {
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
// test changes, (won't affect you)
|
|
36
|
+
if (baseHost == '/demo/1' || baseHost == '/demo/') {
|
|
37
|
+
return {
|
|
38
|
+
error: 'This book is not available to browse at this time. Please try again later.',
|
|
39
|
+
// error: 'This book is not available to borrow at this time. Please try again later.',
|
|
40
|
+
};
|
|
41
41
|
}
|
|
42
|
+
|
|
43
|
+
// The response is a Response instance.
|
|
44
|
+
// You parse the data into a useable format using `.json()`
|
|
45
|
+
return response.json();
|
|
42
46
|
})
|
|
43
|
-
.
|
|
44
|
-
|
|
47
|
+
.then(data => {
|
|
48
|
+
// `data` is the parsed version of the JSON returned from the above endpoint.
|
|
49
|
+
console.log('actual reponse for endpoint', data);
|
|
50
|
+
if (!data.error) {
|
|
51
|
+
option?.success(data);
|
|
52
|
+
} else {
|
|
53
|
+
option?.error(data);
|
|
54
|
+
}
|
|
45
55
|
});
|
|
46
56
|
}
|
|
47
|
-
|
|
48
|
-
function showActionButtonLoader() {
|
|
49
|
-
const collapsibleElement = document
|
|
50
|
-
.querySelector('ia-book-actions')
|
|
51
|
-
.shadowRoot.querySelector('collapsible-action-group');
|
|
52
|
-
collapsibleElement.setAttribute('style', 'opacity:0.8; pointer-events:none');
|
|
53
|
-
|
|
54
|
-
const actionLoader = collapsibleElement.shadowRoot.querySelector(
|
|
55
|
-
'.action-loader'
|
|
56
|
-
);
|
|
57
|
-
actionLoader.setAttribute('style', 'visibility: visible');
|
|
58
|
-
}
|
|
@@ -7,10 +7,7 @@ import ActionsHandlerService from './actions-handler-service.js';
|
|
|
7
7
|
*
|
|
8
8
|
* ActionsHandlerService is a function being used to execute
|
|
9
9
|
* APIs based of the request made by user. It consist some parameters are as follows:-
|
|
10
|
-
* 1.
|
|
11
|
-
* 2. identifier: book name.
|
|
12
|
-
* 3. success: This is callback function which will be executed after the API request
|
|
13
|
-
* return reponse as a success.
|
|
10
|
+
* 1. identifier: book name.
|
|
14
11
|
*/
|
|
15
12
|
|
|
16
13
|
export default class ActionsHandler extends LitElement {
|
|
@@ -90,53 +87,88 @@ export default class ActionsHandler extends LitElement {
|
|
|
90
87
|
}
|
|
91
88
|
|
|
92
89
|
handleBrowseIt() {
|
|
90
|
+
const context = 'browse_book';
|
|
91
|
+
this.toggleActionBarState(context);
|
|
92
|
+
|
|
93
93
|
ActionsHandlerService({
|
|
94
|
-
action:
|
|
94
|
+
action: context,
|
|
95
95
|
identifier: this.identifier,
|
|
96
96
|
success: () => {
|
|
97
97
|
this.handleReadItNow();
|
|
98
98
|
},
|
|
99
|
+
error: data => {
|
|
100
|
+
alert(data.error);
|
|
101
|
+
this.toggleActionBarState(context, data);
|
|
102
|
+
},
|
|
99
103
|
});
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
handleReturnIt() {
|
|
107
|
+
const context = 'return_loan';
|
|
108
|
+
this.toggleActionBarState(context);
|
|
109
|
+
|
|
103
110
|
ActionsHandlerService({
|
|
104
|
-
action:
|
|
111
|
+
action: context,
|
|
105
112
|
identifier: this.identifier,
|
|
106
113
|
success: () => {
|
|
107
114
|
this.deleteLoanCookies();
|
|
108
115
|
URLHelper.goToUrl(`/details/${this.identifier}`, true);
|
|
109
116
|
},
|
|
117
|
+
error: data => {
|
|
118
|
+
alert(data.error);
|
|
119
|
+
this.toggleActionBarState(context);
|
|
120
|
+
},
|
|
110
121
|
});
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
handleBorrowIt() {
|
|
125
|
+
const context = 'borrow_book';
|
|
126
|
+
this.toggleActionBarState(context);
|
|
127
|
+
|
|
114
128
|
ActionsHandlerService({
|
|
115
|
-
action:
|
|
129
|
+
action: context,
|
|
116
130
|
identifier: this.identifier,
|
|
117
131
|
success: () => {
|
|
118
132
|
this.handleReadItNow();
|
|
119
133
|
},
|
|
134
|
+
error: data => {
|
|
135
|
+
alert(data.error);
|
|
136
|
+
this.toggleActionBarState(context, data);
|
|
137
|
+
},
|
|
120
138
|
});
|
|
121
139
|
}
|
|
122
140
|
|
|
123
141
|
handleReserveIt() {
|
|
142
|
+
const context = 'join_waitlist';
|
|
143
|
+
this.toggleActionBarState(context);
|
|
144
|
+
|
|
124
145
|
ActionsHandlerService({
|
|
125
|
-
action:
|
|
146
|
+
action: context,
|
|
126
147
|
identifier: this.identifier,
|
|
127
148
|
success: () => {
|
|
128
149
|
URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
|
|
129
150
|
},
|
|
151
|
+
error: data => {
|
|
152
|
+
alert(data.error);
|
|
153
|
+
this.toggleActionBarState(context);
|
|
154
|
+
},
|
|
130
155
|
});
|
|
131
156
|
}
|
|
132
157
|
|
|
133
158
|
handleRemoveFromWaitingList() {
|
|
159
|
+
const context = 'leave_waitlist';
|
|
160
|
+
this.toggleActionBarState(context);
|
|
161
|
+
|
|
134
162
|
ActionsHandlerService({
|
|
135
|
-
action:
|
|
163
|
+
action: context,
|
|
136
164
|
identifier: this.identifier,
|
|
137
165
|
success: () => {
|
|
138
166
|
URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
|
|
139
167
|
},
|
|
168
|
+
error: data => {
|
|
169
|
+
alert(data.error);
|
|
170
|
+
this.toggleActionBarState(context);
|
|
171
|
+
},
|
|
140
172
|
});
|
|
141
173
|
}
|
|
142
174
|
|
|
@@ -151,6 +183,9 @@ export default class ActionsHandler extends LitElement {
|
|
|
151
183
|
handleReadItNow(extraParam) {
|
|
152
184
|
const currentParams = new URLSearchParams(window.location.search);
|
|
153
185
|
|
|
186
|
+
// Delete the ?q= parameter just after borrow a book. see: WEBDEV-3979
|
|
187
|
+
currentParams.delete('q');
|
|
188
|
+
|
|
154
189
|
if (extraParam) {
|
|
155
190
|
// append extraParam key-value in currentParams
|
|
156
191
|
const extraParams = new URLSearchParams(extraParam);
|
|
@@ -186,4 +221,12 @@ export default class ActionsHandler extends LitElement {
|
|
|
186
221
|
cookie += '; path=/; domain=.archive.org;';
|
|
187
222
|
document.cookie = cookie;
|
|
188
223
|
}
|
|
224
|
+
|
|
225
|
+
toggleActionBarState(context, data = {}) {
|
|
226
|
+
this.dispatchEvent(
|
|
227
|
+
new CustomEvent('toggle-action-bar-state', {
|
|
228
|
+
detail: { context, data },
|
|
229
|
+
})
|
|
230
|
+
);
|
|
231
|
+
}
|
|
189
232
|
}
|
package/src/ia-book-actions.js
CHANGED
|
@@ -22,6 +22,7 @@ export default class IABookActions extends LitElement {
|
|
|
22
22
|
bwbPurchaseUrl: { type: String },
|
|
23
23
|
barType: { type: String },
|
|
24
24
|
sharedObserver: { attribute: false },
|
|
25
|
+
disable: { type: Boolean },
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
28
|
|
|
@@ -40,6 +41,7 @@ export default class IABookActions extends LitElement {
|
|
|
40
41
|
this.primaryColor = 'primary';
|
|
41
42
|
this.secondaryActions = [];
|
|
42
43
|
this.lendingOptions = {};
|
|
44
|
+
this.disable = false;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
disconnectedCallback() {
|
|
@@ -67,8 +69,7 @@ export default class IABookActions extends LitElement {
|
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
browseHasExpired() {
|
|
70
|
-
const
|
|
71
|
-
const currStatus = { ...this.lendingStatus, browsingExpired };
|
|
72
|
+
const currStatus = { ...this.lendingStatus, browsingExpired: true };
|
|
72
73
|
this.lendingStatus = currStatus;
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -173,12 +174,31 @@ export default class IABookActions extends LitElement {
|
|
|
173
174
|
.secondaryActions=${this.secondaryActions}
|
|
174
175
|
.width=${this.width}
|
|
175
176
|
.hasAdminAccess=${this.hasAdminAccess}
|
|
177
|
+
.disabled=${this.disable}
|
|
178
|
+
@toggle-action-bar-state=${this.toggleActionBarState}
|
|
176
179
|
>
|
|
177
180
|
</collapsible-action-group>
|
|
178
181
|
${this.textGroupTemplate} ${this.infoIconTemplate}
|
|
179
182
|
`;
|
|
180
183
|
}
|
|
181
184
|
|
|
185
|
+
toggleActionBarState(e) {
|
|
186
|
+
// toggle activity loader
|
|
187
|
+
this.disable = !this.disable;
|
|
188
|
+
|
|
189
|
+
// update action bar states is book is not available to browse or borrow.
|
|
190
|
+
if (e?.detail?.data?.error) {
|
|
191
|
+
const errorMsg = e.detail.data.error;
|
|
192
|
+
if (errorMsg.match(/not available to browse/gm)) {
|
|
193
|
+
const currStatus = {...this.lendingStatus, available_to_browse: false };
|
|
194
|
+
this.lendingStatus = currStatus;
|
|
195
|
+
} else if (errorMsg.match(/not available to borrow/gm)) {
|
|
196
|
+
const currStatus = { ...this.lendingStatus, available_to_borrow: false };
|
|
197
|
+
this.lendingStatus = currStatus;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
182
202
|
get iconClass() {
|
|
183
203
|
return this.width <= mobileContainerWidth ? 'mobile' : 'desktop';
|
|
184
204
|
}
|
|
@@ -39,6 +39,22 @@ describe('<collapsible-action-group>', () => {
|
|
|
39
39
|
const primaryButton = primaryActionContainer.querySelector('.ia-button');
|
|
40
40
|
expect(primaryButton.innerText).to.equal('Borrow for 1 hour');
|
|
41
41
|
});
|
|
42
|
+
|
|
43
|
+
it('check if loader is active and action-group is disabled', async () => {
|
|
44
|
+
const el = await fixture(container());
|
|
45
|
+
|
|
46
|
+
const primaryActionContainer = el.shadowRoot.querySelector('.primary');
|
|
47
|
+
primaryActionContainer
|
|
48
|
+
.querySelector('.ia-button')
|
|
49
|
+
.dispatchEvent(new CustomEvent('toggle-loader'));
|
|
50
|
+
el.disabled = true;
|
|
51
|
+
await el.updateComplete;
|
|
52
|
+
|
|
53
|
+
expect(el.disabled).to.be.true;
|
|
54
|
+
expect(el.shadowRoot.querySelector('div').classList.contains('disabled')).to
|
|
55
|
+
.be.true;
|
|
56
|
+
});
|
|
57
|
+
|
|
42
58
|
it('fires analytics events', async () => {
|
|
43
59
|
const el = await fixture(container());
|
|
44
60
|
const primaryActionContainer = el.shadowRoot.querySelector('.primary');
|