@internetarchive/ia-book-actions 0.0.6-2 → 0.0.6-6

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 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 = defaultLendingStatus;
99
+ iaBookActions.lendingStatus = canBrowseAndBorrow;
100
100
  iaBookActions.bwbPurchaseUrl = '';
101
101
  iaBookActions.barType = '';
102
102
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@internetarchive/ia-book-actions",
3
- "version": "0.0.6-2",
3
+ "version": "0.0.6-6",
4
4
  "description": "Bookreader actions for borrowable book",
5
5
  "author": "Internet Archive",
6
6
  "license": "AGPL-3.0-only",
@@ -6,6 +6,9 @@ export default css`
6
6
  height: 3.5rem;
7
7
  padding: 1rem 0;
8
8
  }
9
+ .actiongroup {
10
+ display: flex;
11
+ }
9
12
  .action-buttons {
10
13
  display: inline-flex;
11
14
  align-items: center;
@@ -18,7 +18,7 @@ export default function ActionsHandlerService(options) {
18
18
 
19
19
  let baseHost = '';
20
20
  if (window.location.pathname === '/demo/') {
21
- baseHost = `/demo/1`;
21
+ baseHost = `/demo/`;
22
22
  } else {
23
23
  baseHost = `/services/loans/loan`;
24
24
  }
@@ -30,12 +30,27 @@ export default function ActionsHandlerService(options) {
30
30
  fetch(baseHost, {
31
31
  method: 'POST',
32
32
  body: formData,
33
- }).then(response => {
34
- if (response.status === 200) {
35
- option?.success(response);
36
- } else {
37
- option?.error(response);
38
- }
39
- return;
40
- });
33
+ })
34
+ .then(response => {
35
+ // test changes, (won't affect you)
36
+ if (baseHost == '/demo/1' || baseHost == '/demo/') {
37
+ return {
38
+ error:
39
+ 'This book is not available to borrow at this time. Please try again later.',
40
+ };
41
+ }
42
+
43
+ // The response is a Response instance.
44
+ // You parse the data into a useable format using `.json()`
45
+ return response.json();
46
+ })
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
+ }
55
+ });
41
56
  }
@@ -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. action: action name like browse_book, return_book, borrow_book etc...
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 {
@@ -91,7 +88,7 @@ export default class ActionsHandler extends LitElement {
91
88
 
92
89
  handleBrowseIt() {
93
90
  const context = 'browse_book';
94
- this.toggleLoader(context);
91
+ this.ActionError(context);
95
92
 
96
93
  ActionsHandlerService({
97
94
  action: context,
@@ -99,17 +96,16 @@ export default class ActionsHandler extends LitElement {
99
96
  success: () => {
100
97
  this.handleReadItNow();
101
98
  },
102
- error: response => {
103
- console.log(response);
104
- alert(JSON.stringify(response.error));
105
- this.toggleLoader(context);
99
+ error: data => {
100
+ alert(data.error);
101
+ this.ActionError(context, data);
106
102
  },
107
103
  });
108
104
  }
109
105
 
110
106
  handleReturnIt() {
111
107
  const context = 'return_loan';
112
- this.toggleLoader(context);
108
+ this.ActionError(context);
113
109
 
114
110
  ActionsHandlerService({
115
111
  action: context,
@@ -118,17 +114,16 @@ export default class ActionsHandler extends LitElement {
118
114
  this.deleteLoanCookies();
119
115
  URLHelper.goToUrl(`/details/${this.identifier}`, true);
120
116
  },
121
- error: response => {
122
- console.log(response);
123
- alert(JSON.stringify(response.error));
124
- this.toggleLoader(context);
117
+ error: data => {
118
+ alert(data.error);
119
+ this.ActionError(context);
125
120
  },
126
121
  });
127
122
  }
128
123
 
129
124
  handleBorrowIt() {
130
125
  const context = 'borrow_book';
131
- this.toggleLoader(context);
126
+ this.ActionError(context);
132
127
 
133
128
  ActionsHandlerService({
134
129
  action: context,
@@ -136,17 +131,16 @@ export default class ActionsHandler extends LitElement {
136
131
  success: () => {
137
132
  this.handleReadItNow();
138
133
  },
139
- error: response => {
140
- console.log(response);
141
- alert(JSON.stringify(response.error));
142
- this.toggleLoader(context);
134
+ error: data => {
135
+ alert(data.error);
136
+ this.ActionError(context, data);
143
137
  },
144
138
  });
145
139
  }
146
140
 
147
141
  handleReserveIt() {
148
142
  const context = 'join_waitlist';
149
- this.toggleLoader(context);
143
+ this.ActionError(context);
150
144
 
151
145
  ActionsHandlerService({
152
146
  action: context,
@@ -154,17 +148,16 @@ export default class ActionsHandler extends LitElement {
154
148
  success: () => {
155
149
  URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
156
150
  },
157
- error: response => {
158
- console.log(response);
159
- alert(JSON.stringify(response.error));
160
- this.toggleLoader(context);
151
+ error: data => {
152
+ alert(data.error);
153
+ this.ActionError(context);
161
154
  },
162
155
  });
163
156
  }
164
157
 
165
158
  handleRemoveFromWaitingList() {
166
159
  const context = 'leave_waitlist';
167
- this.toggleLoader(context);
160
+ this.ActionError(context);
168
161
 
169
162
  ActionsHandlerService({
170
163
  action: context,
@@ -172,10 +165,9 @@ export default class ActionsHandler extends LitElement {
172
165
  success: () => {
173
166
  URLHelper.goToUrl(URLHelper.getRedirectUrl(), true);
174
167
  },
175
- error: response => {
176
- console.log(response);
177
- alert(JSON.stringify(response.error));
178
- this.toggleLoader(context);
168
+ error: data => {
169
+ alert(data.error);
170
+ this.ActionError(context);
179
171
  },
180
172
  });
181
173
  }
@@ -191,9 +183,6 @@ export default class ActionsHandler extends LitElement {
191
183
  handleReadItNow(extraParam) {
192
184
  const currentParams = new URLSearchParams(window.location.search);
193
185
 
194
- // Delete the ?q= parameter just after borrow a book. see: WEBDEV-3979
195
- currentParams.delete('q');
196
-
197
186
  if (extraParam) {
198
187
  // append extraParam key-value in currentParams
199
188
  const extraParams = new URLSearchParams(extraParam);
@@ -230,10 +219,10 @@ export default class ActionsHandler extends LitElement {
230
219
  document.cookie = cookie;
231
220
  }
232
221
 
233
- toggleLoader(context) {
222
+ ActionError(context, data = {}) {
234
223
  this.dispatchEvent(
235
- new CustomEvent('toggle-loader', {
236
- detail: context,
224
+ new CustomEvent('lendingActionError', {
225
+ detail: { context, data },
237
226
  })
238
227
  );
239
228
  }
@@ -175,23 +175,36 @@ export default class IABookActions extends LitElement {
175
175
  .width=${this.width}
176
176
  .hasAdminAccess=${this.hasAdminAccess}
177
177
  .disabled=${this.disable}
178
- @toggle-loader=${this.toggleLoader}
178
+ @lendingActionError=${this.handleLendingActionError}
179
179
  >
180
180
  </collapsible-action-group>
181
181
  ${this.textGroupTemplate} ${this.infoIconTemplate}
182
182
  `;
183
183
  }
184
184
 
185
- toggleLoader(e) {
186
- // if activity loader is disabled and action is browse or borrow,
187
- // just change the lendingStatus to dynamic update action buttons
188
- if (this.disable && ['browse_book', 'borrow_book'].includes(e.detail)) {
189
- console.log('lendingStatus is changed to redraw action-buttons');
190
- const currStatus = { ...this.lendingStatus, available_to_browse: false };
185
+ handleLendingActionError(e) {
186
+ // toggle activity loader
187
+ this.disable = !this.disable;
188
+
189
+ const context = e?.detail?.context;
190
+ const errorMsg = e?.detail?.data?.error;
191
+
192
+ // update action bar state if book is not available to browse or borrow.
193
+ if (errorMsg && errorMsg.match(/not available to borrow/gm)) {
194
+ let currStatus = this.lendingStatus;
195
+ if (context === 'browse_book') {
196
+ currStatus = {
197
+ ...this.lendingStatus,
198
+ available_to_browse: false,
199
+ };
200
+ } else if (context === 'borrow_book') {
201
+ currStatus = {
202
+ ...this.lendingStatus,
203
+ available_to_borrow: false,
204
+ };
205
+ }
191
206
  this.lendingStatus = currStatus;
192
207
  }
193
-
194
- this.disable = !this.disable;
195
208
  }
196
209
 
197
210
  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({