@bigbinary/neeto-slack-frontend v3.1.8
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
NeetoChatapp. - Select or add a workspace.
- Allow the app to access the Slack workspace.
- You will be redirected to a broken page, change
httpstohttpin the URL and replacespinkartwith 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
Finishstep. - Click
Doneto 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' endAnd then execute:
bundle installAdd this line to your application's
config/routes.rbfile (replaceatto 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 endbin/rails neeto_slack_engine:install:migrations bin/rails db:migrateConfigure model to add below association to the integrable class
has_one :slack_team, as: :integrable, class_name: "NeetoSlackEngine::SlackTeam", dependent: :destroyConfigure the following
Environment VariablesandSecretswith suitable valuesUnder
.envfile: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 NgrokUnder
secrets.ymlfile: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.ymlcan be added under host appconfigdirectory. 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-frontendInstructions 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 theConfigurecomponent.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
Settingscomponent: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 theSettingscomponent.fields: An array of objects containing the fields to be displayed.onEdit: Function to open thePanewhen the Edit button is clicked.slackUrl: Slack workspace url to be displayed.
Settings.EditPanecomponent: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.EditPanecomponent.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 thePanewhen 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: |
7 months ago
9 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago