3.3.4 • Published 2 days ago

@bigbinary/neeto-filters-frontend v3.3.4

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

neeto-filters-nano

The neeto-filters-nano manages filters across neeto products. The nano exports the @bigbinary/neeto-filters-frontend NPM package and neeto-filters-engine Rails engine for development.

Contents

  1. Development with Host Application
  2. Instructions for Publishing
  3. Releasing beta versions

Development with Host Application

Engine

The engine is used to manage filters across neeto products.

Installation

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

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

    bundle install
  3. Add this line to your application's config/routes.rb file:
    mount NeetoFiltersEngine::Engine, at: "/neeto_filters"
  4. Execute the following command to generate the migration to generate the neeto_filters_engine_segments table.

    bundle exec rails neeto_filters_engine:install:migrations
    
    bundle exec rails db:migrate
  5. Add the following line to models/organization.rb file.

    has_many :segments, class_name: "NeetoFiltersEngine::Segment", dependent: :destroy

Usage

You can learn more about setup and usage here: 1. Models 2. Verify Installation

Frontend package

Installation

  1. Install the latest neeto-filters-frontend package using the below command:
    yarn add @bigbinary/neeto-filters-frontend
  2. neeto-filters-frontend has a few peer dependencies that are required for the proper functioning of the package. Install all the peer dependencies using the below command:
    yarn add @bigbinary/neetoui @bigbinary/neeto-icons axios@0.27.2 classnames@2.3.1 dayjs@1.11.1 formik@2.2.0 ramda@0.28.0 react-router-dom@5.3.0 react-router-nav-prompt@0.4.1 react-toastify@9.0.1 yup@0.32.11

Components

1. Filters (source code)

Props

  • isOpen: To specify whether the Pane component is open or not.
  • setIsOpen: To trigger the isOpen state.
  • columns: The list of columns/fields that needs to be represented in the filters pane.
  • onChange: To specify the callback function that is triggered whenever a filter is applied or cleared. This function will get the updated filters as argument.
  • onSelectorsChange: To specify the callback function that is triggered whenever a selector value is changed. This function will get the updated selectors as argument.
  • buttonProps: To specify the props to be passed to the button component.
  • paneProps: To specify the props to be passed to the pane component.
  • isSearchable: To specify whether you need a search bar in filters pane to search through filter fields.
  • className: To specify classes to the Filters component.
  • keyword: To specify the props related to searching.
  • childrenKeys: The list of keys which has to be cleared from url during clear filters operation.
  • children: To specify the custom components specific to the host application.

Configuration

  • Refer to the Filters section for detailed information on the available configurations for the Filters component.

Usage

import React, { useMemo, useState } from "react";

import { Bar, Container, SubHeader } from "neetomolecules";
import { Filters } from "neetoFilters";

const App = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [showMenuBar, setShowMenuBar] = useState(false);

  const { t } = useTranslation();

  return (
      <Container>
        <SubHeader
          rightActionBlock={
            <Filters
              {...{ isOpen, setIsOpen }}
              isSearchable
              columns={FILTER_COLUMNS}
              keyword={SEARCH_TERM_PROPS}
            />
          }
        />
      </Container>
  );
};

export default App;

2. Bar (source code)

Props

  • columns: The list of columns/fields that needs to be represented in the filters pane.
  • onChange: To specify the callback function that is triggered whenever a filter is applied or cleared. This function will get the updated filters as argument.
  • setIsPaneOpen: To trigger the isOpen state.
  • className: To specify classes to the Bar component.
  • keyword: To specify the props related to searching.
  • onSelectorsChange: To specify the callback function that is triggered whenever a selector value is changed. This function will get the updated selectors as argument.
  • childrenKeys: The list of keys which has to be cleared from url during clear filters operation.
  • entity: The entity associated with the filters.
  • defaultSegmentName: The name of segment which results all entities without applying any filter. Default name is "All results".
  • customFilters: To specify the custom components specific to the host application. This should be same as children passed to the Filters component.

All these props must be same as that passed to the Filters component. The option to save filters as segments will be enabled only when the entity prop is passed to the component.

Usage

import React, { useMemo, useState } from "react";

import Bar from "neetomolecules/SubHeader";
import Container from "neetomolecules/Container";

import { Segments, buildFilterColumns } from "neetoFilters";
import useUsers from "hooks/useUsers";

const App = () => {
  const { usersData } = useUsers();
  const [isOpen, setIsOpen] = useState(false);
  const [fields, setFields] = useState([]);

  const { t } = useTranslation();
  const filterColumns = useMemo(
    () =>
      buildFilterColumns({
        names: usersData.names,
        emails: usersData.emails,
        fields,
      }),
    [usersData.users, fields]
  );

  return (
      <Container>
        <SubHeader
          leftActionBlock={
            <Bar
              columns={filterColumns}
              entity="User"
              setIsPaneOpen={setIsOpen}
            />
          }
        />
      </Container>
  );
};

export default App;

3. Segments (source code)

Props

  • columns: The list of columns/fields that needs to be represented in the filters pane.
  • entity: The entity associated with the segments.
  • setIsPaneOpen: To trigger the isOpen state of the filters pane.
  • defaultSegmentName: The name of segment which results all entities without applying any filter. Default name is "All results".
  • customFilters: To specify the custom components specific to the host application. This should be same as children passed to the Filters component.
  • childrenKeys: The list of keys which has to be cleared from url during clear filters operation.

The "columns" prop must be same as that passed to the Filters component.

Usage

import React, { useMemo, useState } from "react";

import MenuBar from "neetomolecules/MenuBar";
import SubHeader from "neetomolecules/SubHeader";

import { Segments, buildFilterColumns } from "neetoFilters";
import useUsers from "hooks/useUsers";

const App = () => {
  const { usersData } = useUsers();
  const [isOpen, setIsOpen] = useState(false);
  const [showMenuBar, setShowMenuBar] = useState(false);
  const [fields, setFields] = useState([]);

  const filterColumns = useMemo(
    () =>
      buildFilterColumns({
        names: usersData.names,
        emails: usersData.emails,
        fields,
      }),
    [usersData.users, fields]
  );

  return (
      <MenuBar showMenu={showMenuBar}>
        <Segments
          columns={filterColumns}
          entity="User"
          setIsFilterPaneOpen={setIsOpen}
        />
      </MenuBar>

  );
};

export default App;

Funtions

1. buildFiltersFromURL (source code)

  • This function takes a list as argument.
  • This list should contains all the filter columns/fields and the value passed to keyword prop of Filters and Bar.
  • It builds the filter payload from the URL search params. This function should be called for initializing the filters state.
  • Usage in neetoTrail.
const [filters, setFilters] = useState(() =>
  buildFiltersFromURL([...SAMPLE_FILTER_COLUMNS, searchTermProps])
);

2. buildSelectorsFromURL (source code)

  • By selectors we mean the filter fields which doesn't have any relation (node) to a DB table column.
    • For example, consider a field in filter pane called Group by. We cannot provide a node to associate it with a column in DB table. Still it can provide an important value which can be used for the computation as if by telling a means by which the records can be grouped after filtering.
    • Fields without a node, among the ones passed as value to the column prop of Filters are considered as selectors.
  • This function takes a list as argument.
  • This list should contains all the filter columns/fields.
  • It builds the selectors' value from the URL search params. This function should be called for initializing the selectors state.
  • selectors will be an object with keys same as provided in filter fields and selected value as its value.
  • Usage in neetoMonitor.
const [selectors, setSelectors] = useState(() =>
  buildSelectorsFromURL(FILTER_COLUMNS)
);

3. buildFilterColumnsFromFields (source code)

The buildFilterColumnsFromFields function is used to generate an array of filter columns based on the provided fields (often referred as custom fields) and selected field names.

Parameters

  • fields (array): An array of field objects representing the available fields.
  • selectedFields (array, optional): An array of strings representing the selected field names. Defaults to an empty array.
  • showRuleSelector (boolean, optional): A boolean value which specify whether to show the rule selector for each filter or not. It is false by default.
  • groupName (string, optional): A name to be given to the group of filters built from fields.
  • Usage in neetoTestify.
const fields = [
  {
    id: "1",
    name: "name",
    kind: "text",
  },
  {
    id: "2",
    name: "age",
    kind: "number",
  },
  // Add more field objects as needed
];

const selectedFields = ["name", "age"];

const filterColumns = buildFilterColumnsFromFields({ fields, selectedFields });

4. useFetchSegments(source code)

The useFetchSegments hook is used to fetch the array of segments based on the provided entity.

Parameters

  • entity: The entity associated with the segments to be fetched.
  • searchTerm: The search term for fetching the segments filtered by names containing the search term.
  const { data: segments = [], isLoading } = useFetchSegments({ entity: "User" });

Basic Usage

Here is an example of how to use the neeto-filters-engine gem assuming that the users table has been created.

class HomeController < ApplicationController
  before_action :load_users

  def index
    @filtered_users = @users.apply_neeto_filters(params[:filters])
    @total_count = @filtered_users.count
  end

  private

    def load_users
      @users = @organization.users
    end
end

Note: If you wish to use select() method after calling apply_neeto_filters(), please note to use reselect() since neeto-filters itself performs a 'select' operation internally.

Here, the param filters is a hash with the following structure, where each node corresponds to a column in the users table.

[
  {
    "conditions": [
      {
        "node": "email",
        "label": "Email Address",
        "type": "text",
        "rule": "contains",
        "value": "bigbinary",
        "conditions_join_type": "AND"
      },
      {
        "node": "timezone",
        "label": "Timezone",
        "type": "text",
        "rule": "is",
        "value": "Asia/Kolkata",
        "conditions_join_type": "AND"
      }
    ],
    "group_join_type": "OR"
  },
  {
    "conditions": [
      {
        "node": "age",
        "label": "Age",
        "type": "number",
        "rule": "greater_than",
        "value": "18",
        "conditions_join_type": "AND"
      }
    ],
    "group_join_type": "AND"
  }
]

The gem filters the users based on the conditions in the filters param. In this case, all the users whose email address contains bigbinary in the Asia/Kolkata timezone or whose age is greater than 18 will be filtered.

How It Works

Base Types

  • Base Types refers to the columns that are directly present in the table on which the apply_neeto_filters method is called.
  • Refer to this video for an overview of the same.

    https://vimeo.com/724478910/e349e361bd

Custom Types

  • Some projects will have custom attributes to the tables that will be added or updated dynamically. NeetoFiltersEngine can handle these attributes by passing the proper filters to the apply_neeto_filters method.
  • The implementation of custom attributes is different for different projects. NeetoFiltersEngine is built in the same way as neetoCRM. If the custom attributes feature needs to be added to a project where the custom attributes implementation is different, you need to override the NeetoFiltersEngine::Custom::BaseSearchService class specifiying the proper join operations.
  • Refer to the below video for an overview of the same.

    https://vimeo.com/724489868/94dfc6cd43

Associated Types

  • Associated types refer to the the columns that are not directly present in the table on which the apply_neeto_filters method is applied. Instead these will be present in another table to which the first table has a foreign key to. For instance, the deals table can have an association with the companies table and the company name can be displayed in the UI. NeetoFiltersEngine can be used to filter these columns by properly specifying the filters.
  • Refer to te below video for an overview of the same.

    https://vimeo.com/724484259/f305257f37

Adding a new type

  • NeetoFiltersEngine provides the following types: text, number, single_option, multi_option, date, time, datetime, date_range, time_range, and tree_select.
  • Sometimes we need to filter attributes that are not present in the available types. In this case a new type needs to be created.
  • In this case, the type needs to be specified to the NPM package by passing the type name and filters prop in the list of columns. The corresponding search service must be created in the app/services/neeto_filters/ folder as well.
  • Refer to te below video for an overview of the same.

    https://vimeo.com/724499299/09e2231780

Working with Dates

Instructions for Publishing

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

Releasing beta versions

  • Push the changes to a target branch for releasing beta version.
  • Update the package version to {latest-version}-beta (if 1.2.34 is the current latest version, it will be 1.2.34-beta) in the target branch for beta release.
  • Draft a new release from the repo with the target branch.
  • Add a new tag and title in the format: version prefixed with v, eg: v1.2.34-beta.
  • Generate release notes.
  • Set the release as a pre-release and publish the release.

If we are releasing a beta version to a product, we have to inform the compliance team as well to avoid overwriting the version with latest version on the next compliance release.

3.3.4

2 days ago

3.3.3

12 days ago

3.3.2

25 days ago

3.3.1

1 month ago

3.2.9

2 months ago

3.2.8

2 months ago

3.2.6

2 months ago

3.2.7

2 months ago

3.2.5

2 months ago

3.2.4

2 months ago

3.3.0

2 months ago

3.3.0-beta.2

3 months ago

3.2.3

3 months ago

3.2.2

3 months ago

3.2.1

3 months ago

3.3.0-beta.1

3 months ago

3.2.0

3 months ago

3.2.0-beta.0

3 months ago

3.2.0-beta.1

3 months ago

3.1.3

3 months ago

3.1.2

4 months ago

3.1.1

4 months ago

3.1.0

4 months ago

3.0.15

4 months ago

3.0.14

4 months ago

3.0.13

4 months ago

3.0.12

5 months ago

3.0.11

5 months ago

3.0.10

5 months ago

3.0.8

6 months ago

3.0.7

6 months ago

3.0.6

6 months ago

3.0.9

6 months ago

2.11.16

11 months ago

2.11.17

11 months ago

2.11.18

10 months ago

2.11.19

10 months ago

2.14.7

6 months ago

2.14.8

6 months ago

2.14.5

6 months ago

2.14.6

6 months ago

2.14.3

6 months ago

2.14.4

6 months ago

2.14.1

6 months ago

2.14.2

6 months ago

2.14.0

7 months ago

3.0.4

6 months ago

3.0.3

6 months ago

3.0.2

6 months ago

3.0.1

6 months ago

3.0.5

6 months ago

3.0.0

6 months ago

2.13.2

7 months ago

2.13.0

7 months ago

2.13.1

7 months ago

2.11.20

10 months ago

2.12.0

10 months ago

2.12.9

9 months ago

2.12.17

7 months ago

2.12.7

9 months ago

2.12.16

7 months ago

2.12.8

9 months ago

2.12.15

7 months ago

2.12.5

9 months ago

2.12.14

7 months ago

2.12.6

9 months ago

2.12.13

8 months ago

2.12.3

10 months ago

2.12.12

8 months ago

2.12.4

10 months ago

2.12.11

8 months ago

2.12.1

10 months ago

2.12.10

8 months ago

2.12.2

10 months ago

2.11.8

11 months ago

2.11.9

11 months ago

2.11.10

11 months ago

2.11.11

11 months ago

2.11.12

11 months ago

2.11.13

11 months ago

2.11.14

11 months ago

2.11.15

11 months ago

2.11.0

1 year ago

2.11.1

1 year ago

2.11.6

12 months ago

2.11.7

12 months ago

2.11.4

1 year ago

2.11.5

1 year ago

2.11.2

1 year ago

2.11.3

1 year ago

2.10.2

1 year ago

2.9.6

1 year ago

2.9.5

1 year ago

2.9.7

1 year ago

2.10.1

1 year ago

2.10.0

1 year ago

2.6.1

1 year ago

2.8.1

1 year ago

2.6.3

1 year ago

2.8.0

1 year ago

2.6.2

1 year ago

2.6.11

1 year ago

2.6.12

1 year ago

2.6.13

1 year ago

2.6.14

1 year ago

2.9.2

1 year ago

2.9.1

1 year ago

2.7.3

1 year ago

2.9.4

1 year ago

2.9.3

1 year ago

2.7.0

1 year ago

2.9.0

1 year ago

2.7.2

1 year ago

2.7.1

1 year ago

2.6.4

1 year ago

2.6.6

1 year ago

2.6.9

1 year ago

2.6.8

1 year ago

2.3.0

1 year ago

2.2.1

1 year ago

2.2.0

1 year ago

2.5.0

1 year ago

2.4.1

1 year ago

2.3.2

1 year ago

2.4.0

1 year ago

2.3.1

1 year ago

2.6.0

1 year ago

2.5.1

1 year ago

2.1.12

1 year ago

2.1.10

1 year ago

2.1.11

1 year ago

2.1.9

1 year ago

2.1.2

1 year ago

2.0.3

1 year ago

2.1.1

1 year ago

2.0.2

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.1.6

1 year ago

2.1.5

1 year ago

2.1.8

1 year ago

2.1.7

1 year ago

2.1.0

1 year ago

2.0.1

1 year ago

2.0.0

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.4.0-beta.2

2 years ago

1.3.1

2 years ago

1.4.0-beta.1

2 years ago

1.3.0

2 years ago

1.2.2

2 years ago

1.1.5

2 years ago