@bigbinary/neeto-api-keys-frontend 2.2.7 → 2.3.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/README.md CHANGED
@@ -128,6 +128,7 @@ for easily finding specific API keys.
128
128
  - `headerProps`: Props for configuring the header section of the component.
129
129
  - `titleHelpPopoverProps`: Props for configuring the help popover in the title
130
130
  section.
131
+ - `zapierIntegrableType` : If the host app has Zapier integration, the table will display Zapier keys only if the integrable type is "Organization." This prop **is required** if the integrable type is not "Organization" and is scoped to another entity.
131
132
 
132
133
  ##### Usage
133
134
 
@@ -3,7 +3,10 @@
3
3
  "common": {
4
4
  "apiKey_one": "API key",
5
5
  "apiKey_other": "API keys",
6
- "never": "Never"
6
+ "never": "Never",
7
+ "general": "General",
8
+ "zapier": "Zapier",
9
+ "type": "Type"
7
10
  },
8
11
  "headers": {
9
12
  "createApiKey": "Add new API key",
@@ -18,7 +21,8 @@
18
21
  "deleteApiKey": "Delete API key?"
19
22
  },
20
23
  "descriptions": {
21
- "deleteApiKey": "You are permanently deleting the API key named <strong>{{name}}</strong>. This cannot be undone."
24
+ "deleteApiKey": "You are permanently deleting the API key named <strong>{{name}}</strong>. This cannot be undone.",
25
+ "deleteZapierApiKey": "You are permanently deleting the API Key <strong>{{name}}</strong>. All associated Zaps with this API Key will be turned off. This can't be undone."
22
26
  }
23
27
  },
24
28
  "buttons": {
@@ -48,7 +52,8 @@
48
52
  "token": "API key",
49
53
  "expiresAt": "Expires at",
50
54
  "createdAt": "Created at",
51
- "status": "Status"
55
+ "status": "Status",
56
+ "type": "Type"
52
57
  }
53
58
  },
54
59
  "fields": {
package/dist/ApiKeys.js CHANGED
@@ -2,7 +2,7 @@ import _defineProperty from '@babel/runtime/helpers/defineProperty';
2
2
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
3
3
  import { useState, useEffect, useRef } from 'react';
4
4
  import { t } from 'i18next';
5
- import { isNotEmpty, isPresent, isNotPresent } from '@bigbinary/neeto-cist';
5
+ import { isNotEmpty, isPresent, humanize, isNotPresent } from '@bigbinary/neeto-cist';
6
6
  import { DEFAULT_PAGE_INDEX, DEFAULT_PAGE_SIZE, PLURAL } from '@bigbinary/neeto-commons-frontend/constants';
7
7
  import { useMutationWithInvalidation, withT, withTitle, useQueryParams, useDebounce } from '@bigbinary/neeto-commons-frontend/react-utils';
8
8
  import Header from '@bigbinary/neeto-molecules/Header';
@@ -11,24 +11,25 @@ import Button from '@bigbinary/neetoui/Button';
11
11
  import { useTranslation, Trans } from 'react-i18next';
12
12
  import { isEmpty, prop } from 'ramda';
13
13
  import { useHistory } from 'react-router-dom';
14
- import { getQueryParams, buildUrl, dateFormat } from '@bigbinary/neeto-commons-frontend/utils';
14
+ import { getQueryParams, buildUrl, dateFormat, dayjs as dayjs$1 } from '@bigbinary/neeto-commons-frontend/utils';
15
15
  import { globalProps as globalProps$1 } from '@bigbinary/neeto-commons-frontend/initializers';
16
16
  import { useQuery } from '@tanstack/react-query';
17
17
  import axios from 'axios';
18
+ import dayjs from 'dayjs';
19
+ import * as yup from 'yup';
18
20
  import HelpPopover from '@bigbinary/neeto-molecules/HelpPopover';
19
21
  import Pane from '@bigbinary/neetoui/Pane';
20
22
  import Typography from '@bigbinary/neetoui/Typography';
21
23
  import NeetoUIForm from '@bigbinary/neetoui/formik/Form';
22
24
  import Input from '@bigbinary/neetoui/formik/Input';
25
+ import Radio from '@bigbinary/neetoui/formik/Radio';
23
26
  import Checkbox from '@bigbinary/neetoui/formik/Checkbox';
24
27
  import ActionBlock from '@bigbinary/neetoui/formik/ActionBlock';
25
28
  import { Field } from 'formik';
26
29
  import NeetoUIDatePicker from '@bigbinary/neetoui/DatePicker';
27
- import dayjs from 'dayjs';
28
30
  import CopyToClipboardButton from '@bigbinary/neeto-molecules/CopyToClipboardButton';
29
31
  import MoreDropdown from '@bigbinary/neeto-molecules/MoreDropdown';
30
32
  import Tag from '@bigbinary/neetoui/Tag';
31
- import * as yup from 'yup';
32
33
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
33
34
  import PageLoader from '@bigbinary/neeto-molecules/PageLoader';
34
35
  import TableWrapper from '@bigbinary/neeto-molecules/TableWrapper';
@@ -107,8 +108,12 @@ var update = function update(_ref) {
107
108
  apiKey: payload
108
109
  });
109
110
  };
110
- var destroy = function destroy(id) {
111
- return axios["delete"]("".concat(API_KEYS_BASE_URL, "/").concat(id));
111
+ var destroy = function destroy(_ref2) {
112
+ var id = _ref2.id,
113
+ params = _ref2.params;
114
+ return axios["delete"]("".concat(API_KEYS_BASE_URL, "/").concat(id), {
115
+ params: params
116
+ });
112
117
  };
113
118
  var apiKeysApi = {
114
119
  fetch: fetch,
@@ -160,10 +165,15 @@ var useDeleteApiKey = function useDeleteApiKey(onSuccess) {
160
165
  });
161
166
  };
162
167
 
168
+ var API_KEY_TYPES = {
169
+ GENERAL: "general",
170
+ ZAPIER: "zapier"
171
+ };
163
172
  var INITIAL_VALUES = {
164
173
  expiresAt: null,
165
174
  label: "",
166
- hasNoExpiry: true
175
+ hasNoExpiry: true,
176
+ type: API_KEY_TYPES.GENERAL
167
177
  };
168
178
  var NEXT_DAY = dayjs().add(1, "day").startOf("day");
169
179
  var VALIDATION_SCHEMA = yup.object({
@@ -184,39 +194,45 @@ var MENU_ITEMS = {
184
194
  };
185
195
 
186
196
  var isInPast = function isInPast(date) {
187
- return dayjs(date).isBefore(dayjs());
197
+ return dayjs$1(date).isBefore(dayjs$1());
188
198
  };
189
199
  var partlyHideToken = function partlyHideToken(key) {
190
200
  return key.slice(-4).padStart(20, "*");
191
201
  };
192
202
  var formatExpiry = function formatExpiry(date) {
193
- return dayjs(date).diff(dayjs(), "day") <= 2 ? dateFormat.fromNow(date) : dateFormat.date(date);
203
+ return dayjs$1(date).diff(dayjs$1(), "day") <= 2 ? dateFormat.fromNow(date) : dateFormat.date(date);
194
204
  };
195
205
  var getMenuItems = function getMenuItems(_ref) {
196
206
  var onEdit = _ref.onEdit,
197
- onDelete = _ref.onDelete;
207
+ onDelete = _ref.onDelete,
208
+ isEditVisible = _ref.isEditVisible;
198
209
  return [{
199
210
  key: MENU_ITEMS.EDIT,
200
211
  label: t("neetoApiKeys.buttons.edit"),
212
+ isVisible: isEditVisible,
213
+ "data-cy": "api-key-edit-button",
201
214
  onClick: onEdit
202
215
  }, {
203
216
  key: MENU_ITEMS.DELETE,
204
217
  label: t("neetoApiKeys.buttons.delete"),
218
+ "data-cy": "api-key-delete-button",
205
219
  onClick: onDelete
206
220
  }];
207
221
  };
208
222
  var buildColumnData = function buildColumnData(_ref2) {
209
223
  var handleDelete = _ref2.handleDelete,
210
- handleEdit = _ref2.handleEdit;
211
- return [{
224
+ handleEdit = _ref2.handleEdit,
225
+ isZapierAvailable = _ref2.isZapierAvailable;
226
+ var columns = [{
212
227
  title: t("neetoApiKeys.table.headers.label"),
213
228
  key: "label",
214
229
  dataIndex: "label",
215
- width: 400,
230
+ width: 200,
216
231
  render: function render(label, apiKey) {
217
232
  return /*#__PURE__*/jsxs("div", {
218
233
  className: "flex items-center justify-between space-x-3",
219
234
  children: [/*#__PURE__*/jsx(Typography, {
235
+ "data-cy": "api-keys-label-field",
220
236
  style: "body2",
221
237
  children: label
222
238
  }), /*#__PURE__*/jsx(MoreDropdown, {
@@ -229,7 +245,8 @@ var buildColumnData = function buildColumnData(_ref2) {
229
245
  },
230
246
  onDelete: function onDelete() {
231
247
  return handleDelete(apiKey);
232
- }
248
+ },
249
+ isEditVisible: apiKey.type === API_KEY_TYPES.GENERAL
233
250
  })
234
251
  })]
235
252
  });
@@ -238,11 +255,12 @@ var buildColumnData = function buildColumnData(_ref2) {
238
255
  title: t("neetoApiKeys.table.headers.token"),
239
256
  key: "token",
240
257
  dataIndex: "token",
241
- width: 400,
258
+ width: 300,
242
259
  render: function render(token) {
243
260
  return /*#__PURE__*/jsxs("div", {
244
261
  className: "flex items-center justify-between gap-x-3",
245
262
  children: [/*#__PURE__*/jsx(Typography, {
263
+ "data-cy": "api-keys-token-field",
246
264
  style: "body2",
247
265
  children: partlyHideToken(token)
248
266
  }), /*#__PURE__*/jsx(CopyToClipboardButton, {
@@ -269,11 +287,14 @@ var buildColumnData = function buildColumnData(_ref2) {
269
287
  title: t("neetoApiKeys.table.headers.expiresAt"),
270
288
  key: "expiresAt",
271
289
  dataIndex: "expiresAt",
272
- width: 200,
290
+ width: 150,
273
291
  render: function render(expiresAt) {
274
- return isPresent(expiresAt) ? formatExpiry(expiresAt) : /*#__PURE__*/jsx(Typography, {
275
- style: "body2",
276
- children: t("neetoApiKeys.common.never")
292
+ return /*#__PURE__*/jsx("span", {
293
+ "data-cy": "api-keys-expires-at-field",
294
+ children: isPresent(expiresAt) ? formatExpiry(expiresAt) : /*#__PURE__*/jsx(Typography, {
295
+ style: "body2",
296
+ children: t("neetoApiKeys.common.never")
297
+ })
277
298
  });
278
299
  }
279
300
  }, {
@@ -282,15 +303,33 @@ var buildColumnData = function buildColumnData(_ref2) {
282
303
  dataIndex: "createdAt",
283
304
  width: 200,
284
305
  render: function render(createdAt) {
285
- return isPresent(createdAt) ? dateFormat.dateTime(createdAt) : /*#__PURE__*/jsx(Typography, {
286
- style: "body2",
287
- children: t("neetoApiKeys.common.never")
306
+ return /*#__PURE__*/jsx("span", {
307
+ "data-cy": "api-keys-created-at-field",
308
+ children: isPresent(createdAt) ? dateFormat.dateTime(createdAt) : /*#__PURE__*/jsx(Typography, {
309
+ style: "body2",
310
+ children: t("neetoApiKeys.common.never")
311
+ })
288
312
  });
289
313
  }
290
314
  }];
315
+ if (isZapierAvailable) {
316
+ columns.splice(2, 0, {
317
+ title: t("neetoApiKeys.table.headers.type"),
318
+ key: "type",
319
+ dataIndex: "type",
320
+ width: 144,
321
+ render: function render(type) {
322
+ return /*#__PURE__*/jsx(Typography, {
323
+ style: "body2",
324
+ children: humanize(type)
325
+ });
326
+ }
327
+ });
328
+ }
329
+ return columns;
291
330
  };
292
331
  var getStartOfTime = function getStartOfTime(time, unit) {
293
- return dayjs(time).startOf(unit);
332
+ return dayjs$1(time).startOf(unit);
294
333
  };
295
334
 
296
335
  function ownKeys$3(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -337,7 +376,11 @@ var Form = withT(function (_ref) {
337
376
  isSubmitting = _ref.isSubmitting,
338
377
  onClose = _ref.onClose,
339
378
  onSubmit = _ref.onSubmit,
340
- initialFocusRef = _ref.initialFocusRef;
379
+ initialFocusRef = _ref.initialFocusRef,
380
+ _ref$isEdit = _ref.isEdit,
381
+ isEdit = _ref$isEdit === void 0 ? false : _ref$isEdit,
382
+ _ref$isZapierAvailabl = _ref.isZapierAvailable,
383
+ isZapierAvailable = _ref$isZapierAvailabl === void 0 ? false : _ref$isZapierAvailabl;
341
384
  return /*#__PURE__*/jsx(NeetoUIForm, {
342
385
  formikProps: {
343
386
  validationSchema: VALIDATION_SCHEMA,
@@ -349,7 +392,8 @@ var Form = withT(function (_ref) {
349
392
  _ref2$values = _ref2.values,
350
393
  _ref2$values2 = _ref2$values === void 0 ? {} : _ref2$values,
351
394
  hasNoExpiry = _ref2$values2.hasNoExpiry,
352
- expiresAt = _ref2$values2.expiresAt;
395
+ expiresAt = _ref2$values2.expiresAt,
396
+ type = _ref2$values2.type;
353
397
  return /*#__PURE__*/jsxs(Fragment, {
354
398
  children: [/*#__PURE__*/jsx(Pane.Body, {
355
399
  children: /*#__PURE__*/jsxs("div", {
@@ -361,23 +405,37 @@ var Form = withT(function (_ref) {
361
405
  placeholder: t("neetoApiKeys.placeholders.label"),
362
406
  ref: initialFocusRef
363
407
  }), /*#__PURE__*/jsxs("div", {
364
- className: "space-y-2",
365
- children: [!hasNoExpiry && /*#__PURE__*/jsx(DatePicker, {
366
- defaultValue: expiresAt,
367
- disabledDate: function disabledDate(date) {
368
- return date < NEXT_DAY;
369
- },
370
- label: t("neetoApiKeys.fields.expiryDate"),
371
- name: "expiresAt",
372
- placeholder: t("neetoApiKeys.placeholders.selectExpiryDate")
373
- }), /*#__PURE__*/jsx(Checkbox, {
374
- checked: hasNoExpiry,
375
- label: t("neetoApiKeys.fields.neverExpire"),
376
- name: "hasNoExpiry",
377
- onChange: function onChange() {
378
- setFieldValue("expiresAt", null);
379
- setFieldValue("hasNoExpiry", !hasNoExpiry);
380
- }
408
+ className: "space-y-4",
409
+ children: [!isEdit && isZapierAvailable && /*#__PURE__*/jsxs(Radio, {
410
+ label: t("neetoApiKeys.common.type"),
411
+ name: "type",
412
+ children: [/*#__PURE__*/jsx(Radio.Item, {
413
+ label: t("neetoApiKeys.common.general"),
414
+ name: "type",
415
+ value: API_KEY_TYPES.GENERAL
416
+ }), /*#__PURE__*/jsx(Radio.Item, {
417
+ label: t("neetoApiKeys.common.zapier"),
418
+ name: "type",
419
+ value: API_KEY_TYPES.ZAPIER
420
+ })]
421
+ }), type === API_KEY_TYPES.GENERAL && /*#__PURE__*/jsxs(Fragment, {
422
+ children: [!hasNoExpiry && /*#__PURE__*/jsx(DatePicker, {
423
+ defaultValue: expiresAt,
424
+ disabledDate: function disabledDate(date) {
425
+ return date < NEXT_DAY;
426
+ },
427
+ label: t("neetoApiKeys.fields.expiryDate"),
428
+ name: "expiresAt",
429
+ placeholder: t("neetoApiKeys.placeholders.selectExpiryDate")
430
+ }), /*#__PURE__*/jsx(Checkbox, {
431
+ checked: hasNoExpiry,
432
+ label: t("neetoApiKeys.fields.neverExpire"),
433
+ name: "hasNoExpiry",
434
+ onChange: function onChange() {
435
+ setFieldValue("expiresAt", null);
436
+ setFieldValue("hasNoExpiry", !hasNoExpiry);
437
+ }
438
+ })]
381
439
  })]
382
440
  })]
383
441
  })
@@ -396,7 +454,9 @@ var Form = withT(function (_ref) {
396
454
 
397
455
  var Create = function Create(_ref) {
398
456
  var onClose = _ref.onClose,
399
- isOpen = _ref.isOpen;
457
+ isOpen = _ref.isOpen,
458
+ _ref$isZapierAvailabl = _ref.isZapierAvailable,
459
+ isZapierAvailable = _ref$isZapierAvailabl === void 0 ? false : _ref$isZapierAvailabl;
400
460
  var initialFocusRef = useRef(null);
401
461
  var _useCreateApiKey = useCreateApiKey(onClose),
402
462
  createApiKey = _useCreateApiKey.mutate,
@@ -421,6 +481,7 @@ var Create = function Create(_ref) {
421
481
  })
422
482
  }), /*#__PURE__*/jsx(Form, {
423
483
  initialFocusRef: initialFocusRef,
484
+ isZapierAvailable: isZapierAvailable,
424
485
  onClose: onClose,
425
486
  isSubmitting: isCreating,
426
487
  onSubmit: createApiKey
@@ -468,6 +529,7 @@ var Update = function Update(_ref) {
468
529
  initialFocusRef: initialFocusRef,
469
530
  initialValues: initialValues,
470
531
  onClose: onClose,
532
+ isEdit: true,
471
533
  isSubmitting: isUpdating,
472
534
  onSubmit: handleUpdate
473
535
  })]
@@ -486,7 +548,8 @@ var Table = function Table(_ref) {
486
548
  data = _ref.data,
487
549
  isLoading = _ref.isLoading,
488
550
  isFetching = _ref.isFetching,
489
- handlePageChange = _ref.handlePageChange;
551
+ handlePageChange = _ref.handlePageChange,
552
+ isZapierAvailable = _ref.isZapierAvailable;
490
553
  var _useTranslation = useTranslation(),
491
554
  t = _useTranslation.t;
492
555
  if (isLoading) return /*#__PURE__*/jsx(PageLoader, {});
@@ -520,15 +583,16 @@ var Table = function Table(_ref) {
520
583
  children: /*#__PURE__*/jsx(NeetoUITable, {
521
584
  handlePageChange: handlePageChange,
522
585
  fixedHeight: true,
523
- columnData: buildColumnData({
524
- handleDelete: handleDelete,
525
- handleEdit: handleEdit
526
- }),
527
586
  currentPageNumber: currentPage,
528
587
  defaultPageSize: DEFAULT_PAGE_SIZE,
529
588
  loading: isFetching,
530
589
  rowData: data === null || data === void 0 ? void 0 : data.apiKeys,
531
- totalCount: data === null || data === void 0 ? void 0 : data.totalCount
590
+ totalCount: data === null || data === void 0 ? void 0 : data.totalCount,
591
+ columnData: buildColumnData({
592
+ handleDelete: handleDelete,
593
+ handleEdit: handleEdit,
594
+ isZapierAvailable: isZapierAvailable
595
+ })
532
596
  })
533
597
  });
534
598
  };
@@ -538,7 +602,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
538
602
  var ApiKeys = function ApiKeys(_ref) {
539
603
  var noDataProps = _ref.noDataProps,
540
604
  headerProps = _ref.headerProps,
541
- titleHelpPopoverProps = _ref.titleHelpPopoverProps;
605
+ titleHelpPopoverProps = _ref.titleHelpPopoverProps,
606
+ _ref$zapierIntegrable = _ref.zapierIntegrableType,
607
+ zapierIntegrableType = _ref$zapierIntegrable === void 0 ? "Organization" : _ref$zapierIntegrable;
542
608
  var _useState = useState({}),
543
609
  _useState2 = _slicedToArray(_useState, 2),
544
610
  apiKeyToBeDeleted = _useState2[0],
@@ -574,7 +640,9 @@ var ApiKeys = function ApiKeys(_ref) {
574
640
  pageSize: DEFAULT_PAGE_SIZE
575
641
  };
576
642
  var _useFetchApiKeys = useFetchApiKeys({
577
- params: queryParams
643
+ params: _objectSpread(_objectSpread({}, queryParams), {}, {
644
+ zapierIntegrableType: zapierIntegrableType
645
+ })
578
646
  }),
579
647
  data = _useFetchApiKeys.data,
580
648
  isLoading = _useFetchApiKeys.isLoading,
@@ -584,6 +652,9 @@ var ApiKeys = function ApiKeys(_ref) {
584
652
  if (!data) return;
585
653
  onFetchSuccess(data);
586
654
  }, [data]);
655
+ var _ref2 = data || {},
656
+ _ref2$isZapierAvailab = _ref2.isZapierAvailable,
657
+ isZapierAvailable = _ref2$isZapierAvailab === void 0 ? false : _ref2$isZapierAvailab;
587
658
  return /*#__PURE__*/jsxs("div", {
588
659
  className: "flex h-full w-full flex-col",
589
660
  children: [/*#__PURE__*/jsx(Header, _objectSpread({
@@ -610,6 +681,7 @@ var ApiKeys = function ApiKeys(_ref) {
610
681
  handlePageChange: handlePageChange,
611
682
  isFetching: isFetching,
612
683
  isLoading: isLoading,
684
+ isZapierAvailable: isZapierAvailable,
613
685
  noDataProps: noDataProps,
614
686
  setIsCreatePaneOpen: setIsCreatePaneOpen,
615
687
  handleDelete: setApiKeyToBeDeleted,
@@ -623,18 +695,24 @@ var ApiKeys = function ApiKeys(_ref) {
623
695
  components: {
624
696
  bold: /*#__PURE__*/jsx("strong", {})
625
697
  },
626
- i18nKey: "neetoApiKeys.alert.descriptions.deleteApiKey",
627
698
  values: {
628
699
  name: apiKeyToBeDeleted.label
629
- }
700
+ },
701
+ i18nKey: apiKeyToBeDeleted.type === API_KEY_TYPES.ZAPIER ? "neetoApiKeys.alert.descriptions.deleteZapierApiKey" : "neetoApiKeys.alert.descriptions.deleteApiKey"
630
702
  }),
631
703
  onClose: function onClose() {
632
704
  return setApiKeyToBeDeleted({});
633
705
  },
634
706
  onSubmit: function onSubmit() {
635
- return deleteApiKey(apiKeyToBeDeleted.id);
707
+ return deleteApiKey({
708
+ id: apiKeyToBeDeleted.id,
709
+ params: {
710
+ type: apiKeyToBeDeleted.type
711
+ }
712
+ });
636
713
  }
637
714
  }), /*#__PURE__*/jsx(Create, {
715
+ isZapierAvailable: isZapierAvailable,
638
716
  isOpen: isCreatePaneOpen,
639
717
  onClose: function onClose() {
640
718
  return setIsCreatePaneOpen(false);