@bigbinary/neeto-access-control-frontend 1.3.3 → 1.3.4

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
@@ -137,6 +137,10 @@ The engine is used to manage access control across neeto products.
137
137
  def owner
138
138
  @organization
139
139
  end
140
+
141
+ def update_owner!
142
+ # Optional override to update the owner if required when configuration is updated
143
+ end
140
144
  end
141
145
  ```
142
146
 
@@ -181,6 +185,10 @@ The engine is used to manage access control across neeto products.
181
185
  - `hideAddEmailsFromInvitationPane`: Prop to hide the add emails form from invitation pane. Default: `false`.
182
186
  - `className`: Additional classes to be added to the form.
183
187
  - `onDestroyInvitationsSuccess`: Callback function that is triggered when the invitations are successfully destroyed.
188
+ - `inviteButtonProps`: If specified, this will show a button on the top of the Pane. It can be used to take the users to invitation forms outside the InvitationsPane.
189
+ - `additionalFieldsInitialValues`: Prop to add additional custom fields to the form.
190
+ - `fieldsWrapper`: A component that wraps the fields in the form. Useful for adding custom fields to the form.
191
+ - `translationContext`: Context for translations, it can be used to override the translations of the field labels. Ref: https://www.i18next.com/translation-function/context
184
192
 
185
193
  #### 2. `Invitations` Object
186
194
  The `Invitations` object provides access to invitation-related components, hooks, and constants.
@@ -200,6 +208,7 @@ The `Invitations` object provides access to invitation-related components, hooks
200
208
  - `hideAddEmailsForm`: Prop to hide the add emails form from invitation pane.
201
209
  - `configurationId`: Prop to specify the ID of the instance of the model. The ID is used to load access control configuration. **NOTE: If this prop is not passed, make sure `invitations_controller_override.rb` is added with `access_control_configuration` method as mentioned above in adding overrides section.**
202
210
  - `onDestroyInvitationsSuccess`: Callback function that is triggered when the invitations are successfully destroyed.
211
+ - `inviteButtonProps`: If specified, this will show a button on the top of the Pane. It can be used to take the users to invitation forms outside the InvitationsPane.
203
212
 
204
213
  #### Hooks
205
214
  - `useBulkCreateInvitations` [source code](/app/javascript/src/hooks/reactQuery/useInvitationsApi.js): Bulk create invitations.Check [usage](app/javascript/src/components/Configuration/Invitations/index.jsx).
package/dist/index.cjs.js CHANGED
@@ -7,12 +7,12 @@ var classNames = require('classnames');
7
7
  var neetoCist = require('@bigbinary/neeto-cist');
8
8
  var Container = require('@bigbinary/neeto-molecules/Container');
9
9
  var Scrollable = require('@bigbinary/neeto-molecules/Scrollable');
10
- var Label = require('@bigbinary/neetoui/Label');
11
10
  var Spinner = require('@bigbinary/neetoui/Spinner');
12
11
  var ActionBlock = require('@bigbinary/neetoui/formik/ActionBlock');
13
12
  var Form = require('@bigbinary/neetoui/formik/Form');
14
13
  var Input = require('@bigbinary/neetoui/formik/Input');
15
14
  var Radio = require('@bigbinary/neetoui/formik/Radio');
15
+ var ramda = require('ramda');
16
16
  var reactI18next = require('react-i18next');
17
17
  var constants = require('@bigbinary/neeto-commons-frontend/constants');
18
18
  var Delete = require('@bigbinary/neeto-icons/Delete');
@@ -24,7 +24,6 @@ var NoData = require('@bigbinary/neetoui/NoData');
24
24
  var Pane = require('@bigbinary/neetoui/Pane');
25
25
  var Table = require('@bigbinary/neetoui/Table');
26
26
  var Typography = require('@bigbinary/neetoui/Typography');
27
- var ramda = require('ramda');
28
27
  var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
29
28
  var reactQuery = require('@tanstack/react-query');
30
29
  var reactUtils = require('@bigbinary/neeto-commons-frontend/react-utils');
@@ -37,6 +36,7 @@ var jsxRuntime = require('react/jsx-runtime');
37
36
  var MoreDropdown = require('@bigbinary/neeto-molecules/MoreDropdown');
38
37
  var Tooltip = require('@bigbinary/neetoui/Tooltip');
39
38
  var formik = require('formik');
39
+ var Label = require('@bigbinary/neetoui/Label');
40
40
  var NeetoHeader = require('@bigbinary/neeto-molecules/Header');
41
41
  var HelpPopover = require('@bigbinary/neeto-molecules/HelpPopover');
42
42
 
@@ -97,14 +97,14 @@ var QUERY_KEYS = {
97
97
  };
98
98
 
99
99
  var _excluded = ["ownerId", "ownerType"];
100
- 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; }
101
- function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
100
+ function ownKeys$4(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; }
101
+ function _objectSpread$4(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$4(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$4(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
102
102
  var ACCESS_CONTROL_CONFIGURATION_INVITATIONS$1 = QUERY_KEYS.ACCESS_CONTROL_CONFIGURATION_INVITATIONS;
103
103
  var useListInvitations = function useListInvitations(_ref, options) {
104
104
  var ownerId = _ref.ownerId,
105
105
  ownerType = _ref.ownerType,
106
106
  otherParams = _objectWithoutProperties(_ref, _excluded);
107
- return reactQuery.useQuery(_objectSpread$3({
107
+ return reactQuery.useQuery(_objectSpread$4({
108
108
  queryKey: [ACCESS_CONTROL_CONFIGURATION_INVITATIONS$1, ownerType, ownerId, otherParams],
109
109
  queryFn: function queryFn() {
110
110
  return invitationsApi.list(otherParams);
@@ -121,7 +121,7 @@ var useBulkCreateInvitations = function useBulkCreateInvitations(_ref2, options)
121
121
  configurationId: configurationId,
122
122
  payload: payload
123
123
  });
124
- }, _objectSpread$3({
124
+ }, _objectSpread$4({
125
125
  keysToInvalidate: [[ACCESS_CONTROL_CONFIGURATION_INVITATIONS$1, ownerType, ownerId]]
126
126
  }, options));
127
127
  };
@@ -134,7 +134,7 @@ var useBulkDestroyInvitations = function useBulkDestroyInvitations(_ref3, option
134
134
  configurationId: configurationId,
135
135
  payload: payload
136
136
  });
137
- }, _objectSpread$3({
137
+ }, _objectSpread$4({
138
138
  keysToInvalidate: [[ACCESS_CONTROL_CONFIGURATION_INVITATIONS$1, ownerType, ownerId]]
139
139
  }, options));
140
140
  };
@@ -257,6 +257,8 @@ var renderColumnData = function renderColumnData(_ref2) {
257
257
  }), extraColumnsData);
258
258
  };
259
259
 
260
+ 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; }
261
+ function _objectSpread$3(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$3(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$3(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
260
262
  var Invitations$1 = function Invitations(_ref) {
261
263
  var _selectedEmails$;
262
264
  var _ref$extraColumnsData = _ref.extraColumnsData,
@@ -270,6 +272,8 @@ var Invitations$1 = function Invitations(_ref) {
270
272
  onClose = _ref.onClose,
271
273
  _ref$hideAddEmailsFor = _ref.hideAddEmailsForm,
272
274
  hideAddEmailsForm = _ref$hideAddEmailsFor === void 0 ? false : _ref$hideAddEmailsFor,
275
+ _ref$inviteButtonProp = _ref.inviteButtonProps,
276
+ inviteButtonProps = _ref$inviteButtonProp === void 0 ? {} : _ref$inviteButtonProp,
273
277
  _ref$onDestroyInvitat = _ref.onDestroyInvitationsSuccess,
274
278
  onDestroyInvitationsSuccess = _ref$onDestroyInvitat === void 0 ? neetoCist.noop : _ref$onDestroyInvitat;
275
279
  var _useState = react.useState([]),
@@ -342,8 +346,11 @@ var Invitations$1 = function Invitations(_ref) {
342
346
  children: t("neetoAccessControl.titles.invitations")
343
347
  })
344
348
  }), /*#__PURE__*/jsxRuntime.jsxs(Pane.Body, {
345
- className: "pt-2",
346
- children: [!hideAddEmailsForm && /*#__PURE__*/jsxRuntime.jsx(AddEmails, {
349
+ className: "space-y-4 pt-2",
350
+ children: [neetoCist.isNotEmpty(inviteButtonProps) && /*#__PURE__*/jsxRuntime.jsx("div", {
351
+ className: "flex w-full justify-end",
352
+ children: /*#__PURE__*/jsxRuntime.jsx(Button$1, _objectSpread$3({}, inviteButtonProps))
353
+ }), !hideAddEmailsForm && /*#__PURE__*/jsxRuntime.jsx(AddEmails, {
347
354
  configurationId: configurationId,
348
355
  ownerId: ownerId,
349
356
  ownerType: ownerType
@@ -494,27 +501,6 @@ var AUTH = {
494
501
  SESSION: "session",
495
502
  INVITED: "invited"
496
503
  };
497
- var AUTH_OPTIONS = [{
498
- label: i18next.t("neetoAccessControl.auth.no"),
499
- value: AUTH.NO,
500
- "data-cy": "access-control-public-access-radio-input"
501
- }, {
502
- label: i18next.t("neetoAccessControl.auth.basic"),
503
- value: AUTH.BASIC,
504
- "data-cy": "access-control-password-protected-radio-input"
505
- }, {
506
- label: i18next.t("neetoAccessControl.auth.invited"),
507
- value: AUTH.INVITED,
508
- "data-cy": "access-control-only-invited-people-radio-input"
509
- }, {
510
- label: i18next.t("neetoAccessControl.auth.email"),
511
- value: AUTH.EMAIL,
512
- "data-cy": "access-control-secure-by-email-patterns-radio-input"
513
- }, {
514
- label: i18next.t("neetoAccessControl.auth.session"),
515
- value: AUTH.SESSION,
516
- "data-cy": "access-control-logged-in-members-only-radio-input"
517
- }];
518
504
  var CONFIGURATION_VALIDATION_SCHEMA = yup__namespace.object({
519
505
  auth: yup__namespace.string().required(i18next.t("neetoAccessControl.inputs.validation.authRequired")),
520
506
  password: yup__namespace.string().nullable().when("auth", {
@@ -579,6 +565,41 @@ var renderLabelWithViewInvitation = function renderLabelWithViewInvitation(_ref2
579
565
  }
580
566
  });
581
567
  };
568
+ var getAuthOptions = function getAuthOptions(_ref3) {
569
+ var translationContext = _ref3.translationContext,
570
+ t = _ref3.t;
571
+ return [{
572
+ label: t("neetoAccessControl.auth.no", {
573
+ context: translationContext
574
+ }),
575
+ value: AUTH.NO,
576
+ "data-cy": "access-control-public-access-radio-input"
577
+ }, {
578
+ label: t("neetoAccessControl.auth.basic", {
579
+ context: translationContext
580
+ }),
581
+ value: AUTH.BASIC,
582
+ "data-cy": "access-control-password-protected-radio-input"
583
+ }, {
584
+ label: t("neetoAccessControl.auth.invited", {
585
+ context: translationContext
586
+ }),
587
+ value: AUTH.INVITED,
588
+ "data-cy": "access-control-only-invited-people-radio-input"
589
+ }, {
590
+ label: t("neetoAccessControl.auth.email", {
591
+ context: translationContext
592
+ }),
593
+ value: AUTH.EMAIL,
594
+ "data-cy": "access-control-secure-by-email-patterns-radio-input"
595
+ }, {
596
+ label: t("neetoAccessControl.auth.session", {
597
+ context: translationContext
598
+ }),
599
+ value: AUTH.SESSION,
600
+ "data-cy": "access-control-logged-in-members-only-radio-input"
601
+ }];
602
+ };
582
603
 
583
604
  var AllowedKeywords = reactUtils.withT(function (_ref) {
584
605
  var t = _ref.t,
@@ -671,11 +692,18 @@ var Configuration = function Configuration(_ref) {
671
692
  hideAddEmailsFromInvitationPane = _ref$hideAddEmailsFro === void 0 ? false : _ref$hideAddEmailsFro,
672
693
  _ref$onDestroyInvitat = _ref.onDestroyInvitationsSuccess,
673
694
  onDestroyInvitationsSuccess = _ref$onDestroyInvitat === void 0 ? neetoCist.noop : _ref$onDestroyInvitat,
674
- children = _ref.children;
695
+ _ref$inviteButtonProp = _ref.inviteButtonProps,
696
+ inviteButtonProps = _ref$inviteButtonProp === void 0 ? {} : _ref$inviteButtonProp,
697
+ _ref$additionalFields = _ref.additionalFieldsInitialValues,
698
+ additionalFieldsInitialValues = _ref$additionalFields === void 0 ? {} : _ref$additionalFields,
699
+ children = _ref.children,
700
+ fieldsWrapper = _ref.fieldsWrapper,
701
+ translationContext = _ref.translationContext;
675
702
  var _useState = react.useState(false),
676
703
  _useState2 = _slicedToArray(_useState, 2),
677
- showInviationsPane = _useState2[0],
678
- setShowInviationsPane = _useState2[1];
704
+ showInvitationsPane = _useState2[0],
705
+ setShowInvitationsPane = _useState2[1];
706
+ var FieldsWrapper = fieldsWrapper || react.Fragment;
679
707
  var _useTranslation = reactI18next.useTranslation(),
680
708
  t = _useTranslation.t;
681
709
  var _useShowConfiguration = useShowConfiguration({
@@ -686,7 +714,7 @@ var Configuration = function Configuration(_ref) {
686
714
  configuration = _useShowConfiguration2 === void 0 ? {} : _useShowConfiguration2,
687
715
  isLoading = _useShowConfiguration.isLoading,
688
716
  isFetching = _useShowConfiguration.isFetching;
689
- var configurationInitialValues = buildConfigurationInitialValues(configuration);
717
+ var configurationInitialValues = ramda.mergeLeft(buildConfigurationInitialValues(configuration), additionalFieldsInitialValues);
690
718
  var _useUpdateConfigurati = useUpdateConfiguration({
691
719
  ownerId: ownerId,
692
720
  ownerType: ownerType
@@ -704,7 +732,7 @@ var Configuration = function Configuration(_ref) {
704
732
  updateConfiguration = _useUpdateConfigurati.mutate;
705
733
  var handleSubmit = function handleSubmit(values, _ref2) {
706
734
  var setSubmitting = _ref2.setSubmitting;
707
- var payload = buildPayload(values);
735
+ var payload = ramda.mergeLeft(buildPayload(values), ramda.pick(ramda.keys(additionalFieldsInitialValues), values));
708
736
  updateConfiguration(payload, {
709
737
  onSettled: function onSettled() {
710
738
  return setSubmitting(false);
@@ -712,7 +740,7 @@ var Configuration = function Configuration(_ref) {
712
740
  });
713
741
  };
714
742
  var handleShowInvitations = onConfigurationChangedToInviteOnly === neetoCist.noop ? function () {
715
- return setShowInviationsPane(true);
743
+ return setShowInvitationsPane(true);
716
744
  } : onConfigurationChangedToInviteOnly;
717
745
  return /*#__PURE__*/jsxRuntime.jsxs(Container, {
718
746
  children: [/*#__PURE__*/jsxRuntime.jsx(Header, {
@@ -734,44 +762,46 @@ var Configuration = function Configuration(_ref) {
734
762
  children: function children(_ref3) {
735
763
  var values = _ref3.values;
736
764
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
737
- children: [/*#__PURE__*/jsxRuntime.jsx(Label, {
738
- className: "neeto-ui-text-base",
739
- children: t("neetoAccessControl.inputs.labels.visibility")
740
- }), /*#__PURE__*/jsxRuntime.jsx(Radio, {
741
- stacked: true,
742
- name: "auth",
743
- children: AUTH_OPTIONS.map(function (props) {
744
- return /*#__PURE__*/react.createElement(Radio.Item, _objectSpread(_objectSpread({}, props), {}, {
745
- key: props.value,
746
- className: classNames({
747
- "items-start": (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED
748
- }),
749
- label: (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED ? renderLabelWithViewInvitation({
750
- onViewInvites: function onViewInvites() {
751
- return setShowInviationsPane(true);
752
- }
753
- }) : props.label,
754
- labelProps: {
765
+ children: [/*#__PURE__*/jsxRuntime.jsxs(FieldsWrapper, {
766
+ children: [/*#__PURE__*/jsxRuntime.jsx(Radio, {
767
+ stacked: true,
768
+ name: "auth",
769
+ children: getAuthOptions({
770
+ translationContext: translationContext,
771
+ t: t
772
+ }).map(function (props) {
773
+ return /*#__PURE__*/react.createElement(Radio.Item, _objectSpread(_objectSpread({}, props), {}, {
774
+ key: props.value,
755
775
  className: classNames({
756
- "flex flex-col items-start justify-start": (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED
757
- })
758
- }
759
- }));
760
- })
761
- }), values.auth === AUTH.BASIC && /*#__PURE__*/jsxRuntime.jsx("div", {
762
- className: "space-y-4 pb-2",
763
- children: /*#__PURE__*/jsxRuntime.jsx(Input, {
764
- autoFocus: true,
765
- required: true,
766
- unlimitedChars: true,
767
- className: "w-7/12",
768
- label: t("neetoAccessControl.inputs.labels.password"),
769
- name: "password",
770
- placeholder: t("neetoAccessControl.inputs.placeholders.enterPassword")
771
- })
772
- }), values.auth === AUTH.EMAIL && /*#__PURE__*/jsxRuntime.jsx(AllowedKeywords, {
773
- label: t("neetoAccessControl.inputs.labels.keywords"),
774
- name: "allowedKeywords"
776
+ "items-start": (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED
777
+ }),
778
+ label: (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED ? renderLabelWithViewInvitation({
779
+ onViewInvites: function onViewInvites() {
780
+ return setShowInvitationsPane(true);
781
+ }
782
+ }) : props.label,
783
+ labelProps: {
784
+ className: classNames({
785
+ "flex flex-col items-start justify-start": (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === props.value && (configuration === null || configuration === void 0 ? void 0 : configuration.auth) === AUTH.INVITED
786
+ })
787
+ }
788
+ }));
789
+ })
790
+ }), values.auth === AUTH.BASIC && /*#__PURE__*/jsxRuntime.jsx("div", {
791
+ className: "space-y-4 pb-2",
792
+ children: /*#__PURE__*/jsxRuntime.jsx(Input, {
793
+ autoFocus: true,
794
+ required: true,
795
+ unlimitedChars: true,
796
+ className: "w-7/12",
797
+ label: t("neetoAccessControl.inputs.labels.password"),
798
+ name: "password",
799
+ placeholder: t("neetoAccessControl.inputs.placeholders.enterPassword")
800
+ })
801
+ }), values.auth === AUTH.EMAIL && /*#__PURE__*/jsxRuntime.jsx(AllowedKeywords, {
802
+ label: t("neetoAccessControl.inputs.labels.keywords"),
803
+ name: "allowedKeywords"
804
+ })]
775
805
  }), /*#__PURE__*/jsxRuntime.jsx(ActionBlock, {
776
806
  cancelButtonProps: {
777
807
  onClick: handleCancel
@@ -783,15 +813,16 @@ var Configuration = function Configuration(_ref) {
783
813
  });
784
814
  }
785
815
  }), /*#__PURE__*/jsxRuntime.jsx(Invitations$1, {
816
+ inviteButtonProps: inviteButtonProps,
786
817
  onDestroyInvitationsSuccess: onDestroyInvitationsSuccess,
787
818
  ownerId: ownerId,
788
819
  ownerType: ownerType,
789
820
  configurationId: configuration.id,
790
821
  extraColumnsData: invitationsTableExtraColumnsData,
791
822
  hideAddEmailsForm: hideAddEmailsFromInvitationPane,
792
- isOpen: showInviationsPane && !isFetching,
823
+ isOpen: showInvitationsPane && !isFetching,
793
824
  onClose: function onClose() {
794
- return setShowInviationsPane(false);
825
+ return setShowInvitationsPane(false);
795
826
  }
796
827
  }), children]
797
828
  })]