@bigbinary/neeto-slack-frontend
v3.1.3
Published
Slack integration step UI
Downloads
4,182
Readme
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
Development with Host Application
Engine
The Engine is used to support the slack integration within neeto applications.
- Log in to the
NeetoChat
app. - Select or add a workspace.
- Allow the app to access the Slack workspace.
- You will be redirected to a broken page, change
https
tohttp
in the URL and replacespinkart
with your workspace name (e.g., "neetochattest"), then press Enter.
- Configure the page by selecting the Slack channel for tickets and click
Continue
. - Proceed to the
Finish
step. - Click
Done
to go to the homepage, where you can manage or disconnect Slack.
Installation
Add this line to your application's Gemfile:
source "NEETO_GEM_SERVER_URL" do # ..existing gems gem 'neeto-slack-engine' end
And then execute:
bundle install
Add this line to your application's
config/routes.rb
file (replaceat
to your desired route):mount NeetoSlackEngine::Engine => "/neeto_slack_engine"
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
Configure model to add below association to the integrable class
has_one :slack_team, as: :integrable, class_name: "NeetoSlackEngine::SlackTeam", dependent: :destroy
Configure the following
Environment Variables
andSecrets
with suitable valuesUnder
.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'] %>
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 appconfig
directory. In case the file is not present the Engine fallbacks to set of default scopes defined under Engine config. File scope structurescopes: v1: bot: ... user: ... v2: bot: ... user: ...
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
Props
handleRedirectToSlack
: Function to handle the redirect to the slack OAuth urlisAuthorizeUrlFetching
: 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
Props
children
: Extra form fields to be included in the Configure page.teamName
: A string representing the Slack team name to be displayed.initialFormValues
: An object containing the initial values for the formik form fields.handleSubmit
: A function to handle the form submit.isSubmitting
: A boolean to handle the loading state of the form.className
: A string to add custom styles to theConfigure
component.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({..}))
channelRefreshHandler
: A function to invalidate queries for refreshing Slack Channel list.channelSelectLabel
: A string to customize the label for Slack Channel select field.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
Props
children
: Extra form fields to be included in the Finish page.secondaryButtonProps
: Props for the secondary button.buttonProps
: Props for the primary button.teamName
: A string representing the Slack team name to be displayed.fields
: An array of objects containing the fields to be displayed.onBack
: Function that handles redirect to Configure page.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
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:
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
Props
Settings
component:children
: Extra form fields to be included in the Settings page.teamName
: A string representing the Slack team name to be displayed.className
: A string to add custom styles to theSettings
component.fields
: An array of objects containing the fields to be displayed.onEdit
: Function to open thePane
when the Edit button is clicked.slackUrl
: Slack workspace url to be displayed.
Settings.EditPane
component:children
: Extra form fields to be included in the EditPane.initialFormValues
: An object containing the initial values for the formik form fields.Include channels array & selectedChannel value
handleSubmit
: A function to handle the form submission.isSubmitting
: A boolean to handle the submitting state of the form.className
: A string to add custom styles to theSettings.EditPane
component.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({..})
onClose
: Function to close thePane
when the Close button is clicked.title
: A string to customize the title of thePane
.isPaneOpen
: A boolean to handle the open/close state of thePane
.channelRefreshHandler
: A function to invalidate queries for refreshing Slack Channel list.paneProps
: Pass down props to the neeto-ui pane
Usage
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:
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 IntegrationintegrableType
: Query param required to fetch Integration connect status through Integrable, passing the record type which is used as integrable for Slack Integration.
Usage
Without Integrable params
const { data: { isSlackIntegrated = "", notificationChannel = "" } = {} } = useFetchSlackIntegrationsStatus({});
References:
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
| Projects | Integrated | | ------------ | :----------------: | | 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: |