2.2.15 • Published 2 months ago

@bigbinary/neeto-slack-frontend v2.2.15

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
2 months ago

neeto-slack-nano

The neeto-slack-nano facilitates the management of slack integration within neeto applictions. The nano exports the @bigbinary/neeto-slack-frontend NPM package and neeto-slack-engine Rails engine for development.

Contents

  1. Development with Host Application
  2. Instructions for Publishing

Development with Host Application

Engine

The Engine is used to support the slack integration within neeto applications.

Installation

  1. Add this line to your application's Gemfile:

     source "NEETO_GEM_SERVER_URL" do
       # ..existing gems
    
       gem 'neeto-slack-engine'
     end
  2. And then execute:

    bundle install
  3. Add this line to your application's config/routes.rb file (replace at to your desired route):

     mount NeetoSlackEngine::Engine => "/neeto_slack_engine"
  4. Install the migrations

    Add a migration to add slack_chat_api_key to Organization of host app if it doesn't exist already. Then run

     # frozen_string_literal: true
    
     class AddSlackChatApiKeyToOrganization < ActiveRecord::Migration[7.0]
       def change
         add_column :organizations, :slack_chat_api_key, :string
       end
     end
    bin/rails neeto_slack_engine:install:migrations
    bin/rails db:migrate
  5. Configure model to add below association to the integrable class

    has_one :slack_team, as: :integrable, class_name: "NeetoSlackEngine::SlackTeam", dependent: :destroy
  6. Configure the following Environment Variables and Secrets with suitable values

    • Under .env file:

      SLACK_CLIENT_ID=# Value from Slack App console at https://api.slack.com/apps/APP_ID/general
      
      SLACK_CLIENT_SECRET=# Valuefrom Slack App console at https://api.slack.com/apps/APP_ID/general
      
      SLACK_CLIENT_SIGNING_SECRET=# Value from Slack App console at https://api.slack.com/apps/APP_ID/general
      
      ATTR_ENCRYPTION_KEY=# Random varying char. key with min. 32 chars.
      
      SLACK_REDIRECT_PATH=#Path controller if Callbacks controller of the application is to be used instead of the one in Engine
      
      SLACK_HOST_URL=# Host url if different than application host URL or in development for use of Ngrok
    • Under secrets.yml file:

      application_name: # Application name
      attr_encrypted:
        encryption_key: <%= ENV['ATTR_ENCRYPTION_KEY'] %>
      slack:
        client_id: "<%= ENV['SLACK_CLIENT_ID'] %>"
        client_secret: <%= ENV['SLACK_CLIENT_SECRET'] %>
        client_signing_secret: <%= ENV['SLACK_CLIENT_SIGNING_SECRET'] %>
  7. Slack Integration supports customizing scopes required for host app on usage basis, for adding/removing the scope file with name neeto_slack_engine.yml can be added under host app config directory. In case the file is not present the Engine fallbacks to set of default scopes defined under Engine config. File scope structure

     scopes:
       v1:
         bot:
         ...
         user:
         ...
       v2:
         bot:
         ...
         user:
         ...

    Ref. - https://github.com/bigbinary/neeto-form-web/blob/0213546cf8a0f4e73e2e5950ceec493d7ad628ea/config/neeto_slack_engine.yml

    Ref. - https://github.com/bigbinary/neeto-slack-engine/blob/e229fec17fd1b7e8596ca1ca55bd2926133fb88f/test/dummy/config/neeto_slack_engine.yml

Frontend package

The package exports components and hooks to manage slack integration within neeto applications.

Installation

Install the latest NeetoSlackNano package using the below command:

yarn add @bigbinary/neeto-slack-frontend

Instructions for development

Check the Frontend package development guide for step-by-step instructions to develop the frontend package.

Components

1. Connect

image

Props
  1. handleRedirectToSlack: Function to handle the redirect to the slack OAuth url

  2. isAuthorizeUrlFetching: Boolean which handles the loading state of Slack Authorize button

Usage
const handleRedirect = () => {
  window.location.assign(slackAuthorizationUrl);
};

return(
  <Connect
    handleRedirectToSlack={handleRedirect}
    isAuthorizeUrlFetching={isAuthorizeUrlFetching}
  />;
);

References:

2. Configure

image

Props
  1. children: Extra form fields to be included in the Configure page.

  2. teamName: A string representing the Slack team name to be displayed.

  3. initialFormValues: An object containing the initial values for the formik form fields.

  4. handleSubmit: A function to handle the form submit.

  5. isSubmitting: A boolean to handle the loading state of the form.

  6. className: A string to add custom styles to the Configure component.

  7. validationSchema: A yup validation schema to validate the form fields.

    Note: No need to include selectedChannel validation. Also no need to wrap validationSchema in yup.object().shape({..}))

  8. channelRefreshHandler: A function to invalidate queries for refreshing Slack Channel list.

  9. channelSelectLabel: A string to customize the label for Slack Channel select field.

  10. slackUrl: Slack workspace url to be displayed.

Usage
  • Without Children

    <Configure
      handleSubmit={handleSubmit}
      isSubmitting={isSubmitting}
      teamName={teamName}
      initialFormValues={{
        selectedChannel: findBy({ value: selectedChannelId }, channelOptions),
        channels: channelOptions,
      }}
    />

    References:

  • With Children

    const SLACK_SETTING_FORM_VALIDATION_SCHEMA = {
      slackEvents: yup.object().nullable().shape({
        faultOccurred: yup.boolean(),
        faultResolved: yup.boolean(),
        faultUnresolved: yup.boolean(),
      }),
    };
    
    // ...
    
    <Configure
      handleSubmit={handleSubmit}
      isSubmitting={isSubmitting}
      teamName={teamName}
      validationSchema={SLACK_SETTING_FORM_VALIDATION_SCHEMA}
      initialFormValues={{
        selectedChannel: findBy({ value: notificationChannelId }, channelOptions),
        channels: channelOptions,
        slackEvents: slackEvents,
      }}
    >
      <Checkbox
        className="neeto-ui-mt-5"
        label="Fault Resolved"
        name="slackEvents.faultResolved"
      />
      <Checkbox
        className="neeto-ui-mt-5"
        label="Fault Unresolved"
        name="slackEvents.faultUnresolved"
      />
      <Checkbox
        className="neeto-ui-my-5"
        label="Fault Occurred"
        name="slackEvents.faultOccurred"
      />
    </Configure>;

    Notes:

    • You can provide the validation schema for the child form fields.
  • Accessing formik props

    <Configure
      handleSubmit={handleSubmit}
      initialFormValues={initialFormValues}
      isSubmitting={isSubmitting}
      teamName={teamName}
    >
      {({ setFieldValue }) => (
        <div className="mb-4 w-full">
          <TimePicker
            use12Hours
            className="text-base font-semibold text-gray-800"
            format="h A"
            interval={{ hourStep: 1, minuteStep: 60, secondStep: 60 }}
            label="Schedule time"
            name="notifyTime"
            type="time"
            onChange={notifyTime => setFieldValue("notifyTime", notifyTime)}
          />
        </div>
      )}
    </Configure>

    References:

3. Finish

image

Props
  1. children: Extra form fields to be included in the Finish page.

  2. secondaryButtonProps: Props for the secondary button.

  3. buttonProps: Props for the primary button.

  4. teamName: A string representing the Slack team name to be displayed.

  5. fields: An array of objects containing the fields to be displayed.

  6. onBack: Function that handles redirect to Configure page.

  7. onSuccess: Function that handles the success case. For example: if there is a demo step, then onSuccess would forward the user to the demo step

Usage
  1. Without Children

    const selectedChannel = "General";
    const { configuration } = useSlackApi();
    
    return (
      <Finish
        selectedChannel={selectedChannel}
        teamName={configuration.teamName}
        fields={[
          {
            name: "Name",
            value: configuration.name,
          },
        ]}
        secondaryButtonProps={{
          label: "Edit",
          onClick: () => setActiveTab("configure"),
        }}
        buttonProps={{ label: "Finish", onClick: onClose }}
      />
    );

    References:

  2. With Children

    const selectedChannel = "General";
    const { configuration } = useSlackApi();
    
    return (
      <Finish
        selectedChannel={selectedChannel}
        teamName={configuration.teamName}
        fields={[
          {
            name: "Name",
            value: configuration.name,
          },
        ]}
        secondaryButtonProps={{
          label: "Edit",
          onClick: () => setActiveTab("configure"),
        }}
        buttonProps={{ label: "Finish", onClick: onClose }}
      >
        <p className="neeto-ui-my-2 neeto-ui-text-info-800">
          *You can update your info later from settings*
        </p>
      </Finish>
    );

4. Settings

image

Props
  • Settings component:

    1. children: Extra form fields to be included in the Settings page.

    2. teamName: A string representing the Slack team name to be displayed.

    3. className: A string to add custom styles to the Settings component.

    4. fields: An array of objects containing the fields to be displayed.

    5. onEdit: Function to open the Pane when the Edit button is clicked.

    6. slackUrl: Slack workspace url to be displayed.

  • Settings.EditPane component:

    1. children: Extra form fields to be included in the EditPane.

    2. initialFormValues: An object containing the initial values for the formik form fields.

      Include channels array & selectedChannel value

    3. handleSubmit: A function to handle the form submission.

    4. isSubmitting: A boolean to handle the submitting state of the form.

    5. className: A string to add custom styles to the Settings.EditPane component.

    6. validationSchema: A yup validation schema to validate the form fields.

      No need to include selectedChannel validation. Also no need to wrap validationSchema in yup.object().shape({..})

    7. onClose: Function to close the Pane when the Close button is clicked.

    8. title: A string to customize the title of the Pane.

    9. isPaneOpen: A boolean to handle the open/close state of the Pane.

    10. channelRefreshHandler: A function to invalidate queries for refreshing Slack Channel list.

    11. paneProps: Pass down props to the neeto-ui pane

Usage
  1. Basic

    const [isPaneOpen, setIsPaneOpen] = useState(false);
    
    const SETTINGS_FORM_INITIAL_VALUES = {
      channels: [
        { label: "general", value: "K87KJHKS987" },
        { label: "hq", value: "IJHKJ76889H" },
      ],
      selectedChannel: { label: "general", value: "K87KJHKS987" },
      updateType: "All conversation activity"
    };
    
    const { slack, handleSubmit, isSubmitting } = useSlackApi();
    const SETTINGS_FORM_VALIDATION_SCHEMA = {
      updateType: yup.string().required(),
    };
    
    return (
      <Settings
        teamName={slack.teamName}
        className="neeto-ui-my-2"
        fields={[
          {
            name: "Channel",
            value: slack.selectedChannel
          },
          {
            name; "Update Type",
            value: slack.updateType
          }
        ]}
        onEdit={() => setIsPaneOpen(true)}
      >
        <Settings.EditPane
          initialFormValues={SETTINGS_FORM_INITIAL_VALUES}
          handleSubmit={handleSubmit}
          isSubmitting={isSubmitting}
          className="neeto-ui-my-2"
          validationSchema={SETTINGS_FORM_VALIDATION_SCHEMA}
          onClose={() => setIsPaneOpen(false)}
          title="Edit slack integration"
          isPaneOpen={isPaneOpen}
        >
          {(formikProps) => (
            <Input name="UpdateType" value={formikProps.values.name} className="neeto-ui-my-2" />
          )}
        </Settings.EditPane>
      </Settings>;
    );

    References:

  2. Accessing formik props for child field elements

    <Settings teamName={teamName} onEdit={handleOpenPane} fields={fields}>
      <Settings.EditPane>
        {({ setFieldValue }) => (
          <div className="mb-4 w-full">
            <TimePicker
              use12Hours
              disabled={isDisabled}
              className="text-base font-semibold text-gray-800"
              format="h A"
              interval={{ hourStep: 1, minuteStep: 60, secondStep: 60 }}
              label="Schedule time"
              name="notifyTime"
              type="time"
              onChange={notifyTime => setFieldValue("notifyTime", notifyTime)}
            />
          </div>
        )}
      </Settings.EditPane>

Hooks

1. useFetchSlackIntegrationsStatus

This is a React Query hook for fetching the status of slack integration.

Arguments
  • integrableId: Query param required to fetch Integration connect status through Integrable, passing the record id which is used as integrable for Slack Integration
  • integrableType: Query param required to fetch Integration connect status through Integrable, passing the record type which is used as integrable for Slack Integration.
Usage
  1. Without Integrable params
    const { data: { isSlackIntegrated = "", notificationChannel = "" } = {} } =
      useFetchSlackIntegrationsStatus({});

    References:

  2. With Integrable params
    const { data: { isSlackIntegrated = "", notificationChannel = "" } = {} } =
      useFetchSlackIntegrationsStatus({
        integrableId: "1234567890",
        integrableType: "Form",
      });

Instructions for Publishing

Consult the building and releasing packages guide for details on how to publish.

Integrations

ProjectsIntegrated
neetoForm:white_check_mark:
neetoChat:white_check_mark:
neetoDesk:white_check_mark:
neetoInvoice:white_check_mark:
neetoMonitor:white_check_mark:
neetoBugtrap:white_check_mark:
neetoCal:white_check_mark:
2.2.15

2 months ago

2.2.14

2 months ago

2.2.13

2 months ago

2.2.11

2 months ago

2.2.12

2 months ago

2.2.10

2 months ago

2.2.9

2 months ago

2.2.8

2 months ago

2.2.7

3 months ago

2.2.6

4 months ago

2.2.5

5 months ago

2.2.4

6 months ago

1.0.0

10 months ago

2.2.1

7 months ago

2.1.2

9 months ago

2.2.0

7 months ago

2.1.1

9 months ago

2.0.2

10 months ago

2.2.3

6 months ago

2.1.4

7 months ago

2.2.2

6 months ago

2.1.3

8 months ago

2.1.5

7 months ago

2.1.0

10 months ago

2.0.1

10 months ago

2.0.0

10 months ago

0.4.3

10 months ago

0.4.2

11 months ago

0.3.9

11 months ago

0.3.10

11 months ago

0.4.1

11 months ago

0.4.0

11 months ago

0.3.8

12 months ago

0.3.7

12 months ago

0.3.6

1 year ago

0.3.5

1 year ago

0.3.4

1 year ago

0.3.3

1 year ago

0.3.2

1 year ago

0.3.1

1 year ago

0.3.0

1 year ago

0.2.2

1 year ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.0

1 year ago