@bigbinary/neeto-access-control-frontend 1.2.0 → 1.2.2

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
@@ -91,7 +91,10 @@ The engine is used to manage access control across neeto products.
91
91
  end
92
92
  ```
93
93
  - 7.2. invitations_controller_override.rb (Optional)
94
- - If host app doesn't have an override method for the controller, then `neeto_access_control_configuration_id` parameter must be included in the request params.
94
+ - Methods
95
+ - `access_control_configuration`
96
+ - `after_invitations_created`
97
+ > If host app doesn't have an override method for the controller, then `neeto_access_control_configuration_id` parameter must be included in the request params.
95
98
 
96
99
  ```ruby
97
100
  NeetoAccessControlEngine::Api::V1::Configurations::InvitationsController.class_eval do
@@ -100,8 +103,17 @@ The engine is used to manage access control across neeto products.
100
103
  def access_control_configuration
101
104
  @_access_control_configuration ||= @organization.access_control_configuration
102
105
  end
106
+
107
+ # after_action callback, called after invitations are created.
108
+ # Use to send invitation emails or perform any post-invitation tasks.
109
+ def after_invitations_created
110
+ # @invited_emails is loaded in engine
111
+ invited_emails = @invited_emails.present? ? @invited_emails.rows.flatten : []
112
+ EmailInvitationsJob.perform_async(invited_emails, current_organization.id, current_user.id)
113
+ end
103
114
  end
104
115
  ```
116
+
105
117
  - 7.3. guest_sessions_controller_override.rb
106
118
 
107
119
  ```ruby
@@ -24,12 +24,13 @@
24
24
  },
25
25
  "buttons": {
26
26
  "saveChangesAndInvite": "Save changes and invite via email",
27
- "addEmails": "Add emails",
27
+ "invite": "Invite",
28
28
  "viewInvites": "View invites"
29
29
  },
30
30
  "addEmails": {
31
31
  "description": "Seperate multiple emails with comma.",
32
- "placeholder": "Enter email(s)"
32
+ "placeholder": "Please enter the email addresses",
33
+ "helpText": "Press space, comma, tab or enter key to add multiple email addresses."
33
34
  },
34
35
  "auth": {
35
36
  "no": "Public, anyone can access",
@@ -56,7 +57,8 @@
56
57
  "passwordRequired": "Password is required",
57
58
  "authRequired": "Authentication type is required",
58
59
  "passwordMinLength": "Password must be at least ${min} characters",
59
- "keywordRequired": "Keyword is required"
60
+ "keywordRequired": "Keyword is required",
61
+ "emailAddress": "Email address is invalid"
60
62
  }
61
63
  }
62
64
  }
package/dist/index.cjs.js CHANGED
@@ -19,7 +19,7 @@ var Delete = require('@bigbinary/neeto-icons/Delete');
19
19
  var SubHeader = require('@bigbinary/neeto-molecules/SubHeader');
20
20
  var TableWrapper = require('@bigbinary/neeto-molecules/TableWrapper');
21
21
  var Alert = require('@bigbinary/neetoui/Alert');
22
- var Button = require('@bigbinary/neetoui/Button');
22
+ var Button$1 = require('@bigbinary/neetoui/Button');
23
23
  var NoData = require('@bigbinary/neetoui/NoData');
24
24
  var Pane = require('@bigbinary/neetoui/Pane');
25
25
  var Table = require('@bigbinary/neetoui/Table');
@@ -28,14 +28,14 @@ var ramda = require('ramda');
28
28
  var reactQuery = require('@tanstack/react-query');
29
29
  var reactUtils = require('@bigbinary/neeto-commons-frontend/react-utils');
30
30
  var axios = require('axios');
31
- var Modal = require('@bigbinary/neetoui/Modal');
32
31
  var MultiEmailInput = require('@bigbinary/neetoui/formik/MultiEmailInput');
33
- var jsxRuntime = require('react/jsx-runtime');
32
+ var Button = require('@bigbinary/neetoui/formik/Button');
34
33
  var i18next = require('i18next');
34
+ var yup = require('yup');
35
+ var jsxRuntime = require('react/jsx-runtime');
35
36
  var MoreDropdown = require('@bigbinary/neeto-molecules/MoreDropdown');
36
37
  var Tooltip = require('@bigbinary/neetoui/Tooltip');
37
38
  var formik = require('formik');
38
- var yup = require('yup');
39
39
  var NeetoHeader = require('@bigbinary/neeto-molecules/Header');
40
40
  var HelpPopover = require('@bigbinary/neeto-molecules/HelpPopover');
41
41
 
@@ -72,17 +72,17 @@ var Delete__default = /*#__PURE__*/_interopDefaultLegacy(Delete);
72
72
  var SubHeader__default = /*#__PURE__*/_interopDefaultLegacy(SubHeader);
73
73
  var TableWrapper__default = /*#__PURE__*/_interopDefaultLegacy(TableWrapper);
74
74
  var Alert__default = /*#__PURE__*/_interopDefaultLegacy(Alert);
75
- var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
75
+ var Button__default$1 = /*#__PURE__*/_interopDefaultLegacy(Button$1);
76
76
  var NoData__default = /*#__PURE__*/_interopDefaultLegacy(NoData);
77
77
  var Pane__default = /*#__PURE__*/_interopDefaultLegacy(Pane);
78
78
  var Table__default = /*#__PURE__*/_interopDefaultLegacy(Table);
79
79
  var Typography__default = /*#__PURE__*/_interopDefaultLegacy(Typography);
80
80
  var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
81
- var Modal__default = /*#__PURE__*/_interopDefaultLegacy(Modal);
82
81
  var MultiEmailInput__default = /*#__PURE__*/_interopDefaultLegacy(MultiEmailInput);
82
+ var Button__default = /*#__PURE__*/_interopDefaultLegacy(Button);
83
+ var yup__namespace = /*#__PURE__*/_interopNamespace(yup);
83
84
  var MoreDropdown__default = /*#__PURE__*/_interopDefaultLegacy(MoreDropdown);
84
85
  var Tooltip__default = /*#__PURE__*/_interopDefaultLegacy(Tooltip);
85
- var yup__namespace = /*#__PURE__*/_interopNamespace(yup);
86
86
  var NeetoHeader__default = /*#__PURE__*/_interopDefaultLegacy(NeetoHeader);
87
87
  var HelpPopover__default = /*#__PURE__*/_interopDefaultLegacy(HelpPopover);
88
88
 
@@ -295,11 +295,14 @@ var TRUNCATE_LENGTH = 45;
295
295
  var ADD_EMAILS_FORM_INIT_VALUES = {
296
296
  emails: []
297
297
  };
298
+ var ADD_EMAILS_FORM_VALDATION_SCHEMA = yup__namespace.object().shape({
299
+ emails: yup__namespace.array().test("are-all-emails-valid", i18next.t("neetoAccessControl.inputs.validation.emailAddress"), function (emails) {
300
+ return emails.every(ramda.prop("valid"));
301
+ })
302
+ });
298
303
 
299
304
  var AddEmails = function AddEmails(_ref) {
300
- var isOpen = _ref.isOpen,
301
- onClose = _ref.onClose,
302
- configurationId = _ref.configurationId,
305
+ var configurationId = _ref.configurationId,
303
306
  ownerType = _ref.ownerType,
304
307
  ownerId = _ref.ownerId;
305
308
  var _useTranslation = reactI18next.useTranslation(),
@@ -313,50 +316,41 @@ var AddEmails = function AddEmails(_ref) {
313
316
  addEmails = _useBulkCreateInvitat.mutate;
314
317
  var handleAddEmails = function handleAddEmails(_ref2, _ref3) {
315
318
  var emails = _ref2.emails;
316
- var setSubmitting = _ref3.setSubmitting;
319
+ var setSubmitting = _ref3.setSubmitting,
320
+ resetForm = _ref3.resetForm;
317
321
  var payload = {
318
322
  emails: ramda.pluck("value", emails)
319
323
  };
320
324
  addEmails(payload, {
321
325
  onSuccess: function onSuccess() {
322
- onClose();
326
+ setSubmitting(false);
327
+ resetForm();
323
328
  },
324
329
  onError: function onError() {
325
330
  return setSubmitting(false);
326
331
  }
327
332
  });
328
333
  };
329
- return /*#__PURE__*/jsxRuntime.jsxs(Modal__default["default"], {
330
- isOpen: isOpen,
331
- onClose: onClose,
332
- initialFocusRef: emailsInputRef,
333
- children: [/*#__PURE__*/jsxRuntime.jsx(Modal__default["default"].Header, {
334
- description: t("neetoAccessControl.addEmails.description"),
335
- children: /*#__PURE__*/jsxRuntime.jsx(Typography__default["default"], {
336
- style: "h2",
337
- children: t("neetoAccessControl.buttons.addEmails")
334
+ return /*#__PURE__*/jsxRuntime.jsxs(Form__default["default"], {
335
+ className: "mb-5 flex w-full space-x-5",
336
+ formikProps: {
337
+ initialValues: ADD_EMAILS_FORM_INIT_VALUES,
338
+ onSubmit: handleAddEmails,
339
+ validationSchema: ADD_EMAILS_FORM_VALDATION_SCHEMA
340
+ },
341
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
342
+ className: "flex-grow",
343
+ children: /*#__PURE__*/jsxRuntime.jsx(MultiEmailInput__default["default"], {
344
+ helpText: t("neetoAccessControl.addEmails.helpText"),
345
+ label: t("neetoAccessControl.titles.emails"),
346
+ name: "emails",
347
+ placeholder: t("neetoAccessControl.addEmails.placeholder"),
348
+ ref: emailsInputRef
338
349
  })
339
- }), /*#__PURE__*/jsxRuntime.jsxs(Form__default["default"], {
340
- formikProps: {
341
- initialValues: ADD_EMAILS_FORM_INIT_VALUES,
342
- onSubmit: handleAddEmails
343
- },
344
- children: [/*#__PURE__*/jsxRuntime.jsx(Modal__default["default"].Body, {
345
- children: /*#__PURE__*/jsxRuntime.jsx(MultiEmailInput__default["default"], {
346
- name: "emails",
347
- placeholder: t("neetoAccessControl.addEmails.placeholder"),
348
- ref: emailsInputRef
349
- })
350
- }), /*#__PURE__*/jsxRuntime.jsx(Modal__default["default"].Footer, {
351
- children: /*#__PURE__*/jsxRuntime.jsx(ActionBlock__default["default"], {
352
- cancelButtonProps: {
353
- onClick: onClose
354
- },
355
- submitButtonProps: {
356
- label: t("neetoAccessControl.buttons.addEmails")
357
- }
358
- })
359
- })]
350
+ }), /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
351
+ className: "flex-shrink-0 self-center whitespace-nowrap",
352
+ label: t("neetoAccessControl.buttons.invite"),
353
+ type: "submit"
360
354
  })]
361
355
  });
362
356
  };
@@ -419,14 +413,10 @@ var Invitations = function Invitations(_ref) {
419
413
  _useState4 = _slicedToArray(_useState3, 2),
420
414
  showDeleteAlert = _useState4[0],
421
415
  setShowDeleteAlert = _useState4[1];
422
- var _useState5 = react.useState(false),
416
+ var _useState5 = react.useState(constants.DEFAULT_PAGE_INDEX),
423
417
  _useState6 = _slicedToArray(_useState5, 2),
424
- showAddEmails = _useState6[0],
425
- setShowAddEmails = _useState6[1];
426
- var _useState7 = react.useState(constants.DEFAULT_PAGE_INDEX),
427
- _useState8 = _slicedToArray(_useState7, 2),
428
- page = _useState8[0],
429
- setPage = _useState8[1];
418
+ page = _useState6[0],
419
+ setPage = _useState6[1];
430
420
  var _useTranslation = reactI18next.useTranslation(),
431
421
  t = _useTranslation.t;
432
422
  var _useListInvitations = useListInvitations({
@@ -453,9 +443,6 @@ var Invitations = function Invitations(_ref) {
453
443
  }),
454
444
  deleteEmailInvites = _useBulkDestroyInvita.mutate,
455
445
  isPending = _useBulkDestroyInvita.isPending;
456
- var handleAddEmails = function handleAddEmails() {
457
- setShowAddEmails(true);
458
- };
459
446
  var handleOnClose = function handleOnClose() {
460
447
  onClose();
461
448
  setSelectedEmails([]);
@@ -486,25 +473,30 @@ var Invitations = function Invitations(_ref) {
486
473
  weight: "semibold",
487
474
  children: t("neetoAccessControl.titles.invitations")
488
475
  })
489
- }), /*#__PURE__*/jsxRuntime.jsx(Pane__default["default"].Body, {
476
+ }), /*#__PURE__*/jsxRuntime.jsxs(Pane__default["default"].Body, {
490
477
  className: "pt-2",
491
- children: neetoCist.isNotEmpty(invitations) ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
478
+ children: [/*#__PURE__*/jsxRuntime.jsx(AddEmails, {
479
+ configurationId: configurationId,
480
+ ownerId: ownerId,
481
+ ownerType: ownerType
482
+ }), neetoCist.isNotEmpty(invitations) ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
492
483
  children: [/*#__PURE__*/jsxRuntime.jsx(SubHeader__default["default"], {
493
484
  leftActionBlock: ramda.isEmpty(selectedEmails) ? /*#__PURE__*/jsxRuntime.jsx(Typography__default["default"], {
485
+ className: "min-h-8",
494
486
  component: "h4",
495
487
  style: "h4",
496
488
  children: t("neetoAccessControl.titles.emailsWithCount", {
497
489
  count: totalCount
498
490
  })
499
491
  }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
500
- className: "flex items-center gap-4",
492
+ className: "flex items-center gap-x-4",
501
493
  children: [/*#__PURE__*/jsxRuntime.jsx(Typography__default["default"], {
502
494
  style: "h4",
503
495
  children: t("neetoAccessControl.titles.selectedEmailsWithCount", {
504
496
  count: selectedEmails.length,
505
497
  totalCount: totalCount
506
498
  })
507
- }), /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
499
+ }), /*#__PURE__*/jsxRuntime.jsx(Button__default$1["default"], {
508
500
  icon: Delete__default["default"],
509
501
  style: "secondary",
510
502
  tooltipProps: {
@@ -514,10 +506,6 @@ var Invitations = function Invitations(_ref) {
514
506
  return setShowDeleteAlert(true);
515
507
  }
516
508
  })]
517
- }),
518
- rightActionBlock: /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
519
- label: t("neetoAccessControl.buttons.addEmails"),
520
- onClick: handleAddEmails
521
509
  })
522
510
  }), /*#__PURE__*/jsxRuntime.jsx(TableWrapper__default["default"], {
523
511
  hasPagination: totalCount > constants.DEFAULT_PAGE_SIZE,
@@ -541,22 +529,10 @@ var Invitations = function Invitations(_ref) {
541
529
  }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
542
530
  className: "flex h-full w-full justify-center",
543
531
  children: [!isLoading && /*#__PURE__*/jsxRuntime.jsx(NoData__default["default"], {
544
- title: t("neetoAccessControl.labels.noInvitations"),
545
- primaryButtonProps: {
546
- label: t("neetoAccessControl.buttons.addEmails"),
547
- onClick: handleAddEmails
548
- }
532
+ title: t("neetoAccessControl.labels.noInvitations")
549
533
  }), isLoading && /*#__PURE__*/jsxRuntime.jsx(PageLoader__default["default"], {})]
550
- })
534
+ })]
551
535
  })]
552
- }), /*#__PURE__*/jsxRuntime.jsx(AddEmails, {
553
- configurationId: configurationId,
554
- ownerId: ownerId,
555
- ownerType: ownerType,
556
- isOpen: showAddEmails,
557
- onClose: function onClose() {
558
- return setShowAddEmails(false);
559
- }
560
536
  }), /*#__PURE__*/jsxRuntime.jsx(Alert__default["default"], {
561
537
  isOpen: showDeleteAlert,
562
538
  isSubmitting: isPending,
@@ -721,7 +697,7 @@ var renderLabelWithViewInvitation = function renderLabelWithViewInvitation(_ref2
721
697
  return /*#__PURE__*/jsxRuntime.jsx(reactI18next.Trans, {
722
698
  i18nKey: "neetoAccessControl.auth.invitedWithViewButton",
723
699
  components: {
724
- button: /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
700
+ button: /*#__PURE__*/jsxRuntime.jsx(Button__default$1["default"], {
725
701
  className: "mt-1",
726
702
  size: "small",
727
703
  style: "link",
@@ -752,7 +728,7 @@ var AllowedKeywords = reactUtils.withT(function (_ref) {
752
728
  className: "w-full",
753
729
  name: "".concat(name, ".").concat(index),
754
730
  placeholder: t("neetoAccessControl.inputs.placeholders.enterKeyword"),
755
- suffix: showDeleteButton && /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
731
+ suffix: showDeleteButton && /*#__PURE__*/jsxRuntime.jsx(Button__default$1["default"], {
756
732
  "data-cy": "allowed-keyword-delete-button",
757
733
  icon: Delete__default["default"],
758
734
  size: "small",
@@ -766,7 +742,7 @@ var AllowedKeywords = reactUtils.withT(function (_ref) {
766
742
  }
767
743
  })
768
744
  }, index);
769
- }), /*#__PURE__*/jsxRuntime.jsx(Button__default["default"], {
745
+ }), /*#__PURE__*/jsxRuntime.jsx(Button__default$1["default"], {
770
746
  className: "pt-2",
771
747
  "data-cy": "add-allowed-keyword-button",
772
748
  label: t("neetoAccessControl.actions.addKeyword"),