New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@bigbinary/neeto-fields-frontend

Package Overview
Dependencies
Maintainers
12
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bigbinary/neeto-fields-frontend

A repo acts as the source of truth for the new nano's structure, configs, data etc.

  • 1.1.5
  • npm
  • Socket score

Version published
Weekly downloads
0
decreased by-100%
Maintainers
12
Weekly downloads
 
Created
Source

neeto-fields-nano

neeto-fields-nano enables the management of dynamically added fields (often referred as custom fields) for the resources across neeto products.

Index

General information

  • This nano deals with fields and field values.

  • Field has a name, kind, resource_type and owner.

  • Field value has a field and resource item associated to it.

  • resource_type is the type of resource for which we are creating the field. It is used for the categorized fetching and rendering of the fields. eg: users, tickets, deals, etc

  • owner is basically scope of a field. It is whom to the field belongs. eg: Organization, Project, etc

  • kind is the nature of the data meant as value for the field. All available kinds are:

    text, number, monetary, single_option, multi_option, date, time, date_range, time_range, textarea, person, checkbox, regex, integer, decimal, datetime.

Installation instructions

Engine installation

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

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

    bundle install
    
  3. Add this line to your application's config/routes.rb file

     mount NeetoFieldsEngine::Engine => "/neeto_fields_engine"
    
  4. Add required migrations in the db/migrate folder. Run the following commands to generate the migrations.

rails g neeto_fields_engine:install

This will generate the migration to create the neeto_fields_engine_fields table (which holds the fields) and neeto_fields_engine_field_values table (which holds the value for the fields).

  1. Run the following command to create the tables.
  rails db:migrate
  1. Generate the required associations between models using the following command:
rails g neeto_fields_engine:associations

This will prompt the user to enter 2 things:

  1. Name of Owner model.
  2. Names of Resource models.
  • Owner: It is the ultimate owner of the fields being added. It can be Organization, Project, etc depending on the business logic. The field will belongs_to Owner.

  • Resource: These are the models, to which we want the dynamic fields to be attached with. This case be anything like Ticket, Deal, etc depending on the business logic. The field_value belongs_to each Resource.

Once you enter the appropriate entries for the prompts asked. It will create an initializer file, which is required for the functioning of the engine.

It will also add necessary associations to respective models, which were considered as Owner and Resources.

Note: You might need to re-arrange the associations statements which are normally inserted to top most lines of the file, to satisfy the Rails standards.

Once you have completed these steps, you are ready to use the neeto-fields-engine.

Frontend package installation

Install the latest neetoFields nano package using the below command:

yarn add @bigbinary/neeto-fields-frontend

The frontend package exports 4 components, 2 utility functions and a hook.

Components

1. FieldsDashboard

Dashboard image

The FieldsDashboard component serves as a dashboard for managing all custom-field related operations. It functions without requiring any props by default, but you can customize its behavior by passing optional props.

Props:
  1. rowData: Represents the rowData for the table within the dashboard.

  2. buildColumnData : A function that builds the column data (in neetoUI table format) for the dashboard table. This function gets the onDeleteClick, onEditClick callbacks and defaultColumns as arguments.

  3. showOwnersInMenu: Accepts a boolean value. When set to true, the fields are displayed in categorized form (side menu) based on owners. By default, fields are categorized based on the resourceType.

  4. resourceType: Explicitly specifies the resource_type of the fields to be shown in the dashboard table. This prop is expected when showOwnersInMenu is set to true.

  5. allowedKinds:Specifies the list of field kinds allowed to be created.

  6. paneProps: Props to be passed to the Add/Edit pane. It accepts the following.

    • children: The children components to be rendered inside the pane.
    • validations: The validations for the formik input fields in the children. validations must be provided as an object with the field name as key and the corresponding yup validation schema as the value.
    • initialValues: The initial values for the formik input fields in the children. It is provided as an object with the field name as key and the corresponding value.
    • hideRequiredSwitch: A boolean value when set to true hides the toggle switch for isRequried.
    • onMutationSuccess: Callback function which is triggered on the success of mutation functions (create, update & delete).
  7. showStateFilter: Boolean value which specifies whether to show or hide state filters.

  8. fieldStatesTaxonomy: Specifies the names to be rendered for active and inactive states.

  9. breadcrumbs: Specifies the breadcrumbs to be displayed on the dashboard page.

  10. helpDocUrl: Specify the URL to the help documentation about fields. This URL will be shown in the NoData screen.

  11. nameAliases: This property accepts alias names as key-value pairs to be displayed for the names of resource types in header and menubar.

  12. headerTitle: Specify the header title explicitly. Default is 'fields'

  13. resources: For owner-based field categorization, provide an array of objects with id and name properties for each owner. For resource type-based categorization, use an array of strings representing resource types.

    If no resources are provided, for resource type-based categorization, the menu bar will fetch all resource types. For owner-based categorization, it will fetch and list all owners in the organization.

Usage:

When Organization is the owner of the fields.

import { FieldsDashboard } from "@bigbinary/neeto-fields-frontend";

<FieldsDashboard
  allowedKinds={["text", "number"]}
  buildColumnData={({ defaultColumns }) => [
    ...defaultColumns,
    {
      dataIndex: "isSystem",
      index: "isSystem",
      title: t("titles.systemField"),
      render: boolVal => (boolVal ? "Yes" : "No"),
    },
  ]}
  fieldStatesTaxonomy={{ active: "Active", inactive: "Deactivated" }}
  paneProps={{
    children: <HostSpecificInputFields />,
    validations: {
      hostSpecificInputName: validationSchema,
    },
    initialValues: {
      hostSpecificInputName: initialValue,
    },
  }}
  breadcrumbs={[
    {
      link: "/",
      text: "Home",
    },
    {
      link: "/",
      text: "Settings",
    },
  ]}
/>;

When Organization is not owner of the fields. Lets say the owner is Project.

import { FieldsDashboard } from "@bigbinary/neeto-fields-frontend";

<FieldsDashboard
  allowedKinds={["text", "number"]}
  ownerId={projectId}
  resourceType="tasks"
  showOwnersInMenu
  fieldStatesTaxonomy={{ active: "Active", inactive: "Deactivated" }}
  paneProps={{
    children: <HostSpecificInputFields />,
    validations: {
      hostSpecificInputName: validationSchema,
    },
    initialValues: {
      hostSpecificInputName: initialValue,
    },
  }}
  breadcrumbs={[
    {
      link: "/",
      text: "Home",
    },
    {
      link: "/",
      text: "Settings",
    },
  ]}
/>;

2. FieldsPane

AddField component gif

This is the pane which handles the Add / Edit operations of the field.

Props:
  1. isOpen: Boolean state which specifies the open/close state of the pane.
  2. onClose: The function to be executed on closing the pane.
  3. resourceType: Specifies the resource_type of the field to be created via the pane.
  4. allowedKinds: Specifies the list of field kinds allowed to be created.
  5. children: Children components for the pane.
  6. additionalValidations: Validations for the formik fields in children.
  7. initialValues: Initial values for the formik fields in children.
  8. selectedField: The field object whose editing is concerned with. If this prop is given, the pane will act as an Edit pane. Else it act as Add pane.
  9. hideRequiredSwitch: Specify whether to hide the Is required toggle switch for field in pane.
  10. ownerId: The ID of the owner in case the owner is not an organization.
  11. onMutationSuccess: The callback function which is triggered on the success of mutation functions( create, update & delete).
Usage:
import { AddField } from "@biginary/neeto-fields-frontend";

<AddField
  allowedKinds={["text", "number"]}
  resourceType="users"
  additionalValidations={{
    hostSpecificInputName: validationSchema,
  }}
  initialValues={{ hostSpecificInputName: initialValue }}
>
  <HostSpecificInputFields />
</AddField>;

3. FieldValuesContainer

FieldValuesContainer Image

The FieldValuesContainer component handles field values associated with a specific resource.

Props:
  1. resourceType: The type of resource.
  2. fieldValues: Field values associated with the resource obtained from the response.
  3. fields: Fields associated with resource type. This is an optional prop. If not provided the component will fetch the fields internally.
  4. resourceId: The ID of the resource.
  5. ownerId:The ID of the owner. This prop is required only if the owner is not an organization.
  6. customComponents: If the host application has any extra kind other than the supported ones, you can specify the component to be displayed corresponding to that kind using this prop. It takes the kind name as the key and the component rendering callback function as the value. The callback function can expect the field object as argument.
  7. className: Class names for styling.
  8. showBorder: Boolean value to specify whether to show or hide borders. Default true.
  9. formRefs: A React Ref object that can be used to access the Formik context of the forms corresponding to each field as key value pairs.
  10. disabled: Boolean value to specify whether to disable all fields.
  11. isRequiredColumnName: The name of column which holds the value which suggests if a field value is a required one or not. Default is isRequired column.
  12. fieldContainerClassName: Class names for styling the div containing the input field.
  13. fieldClassName: Class names for styling the field.
  14. labelClassName: Class names for styling the label for fields.
  15. onMutationSuccess: The callback function which is triggered on the success of mutation functions( create, update & delete).
Usage:

Say the resource over here is a user.

import { FieldValuesContainer } from "@bigbinary/neeto-fields-frontend";

const formRefs = useRef({});
const queryClient = useQueryClient();

<FieldValuesContainer
  formRefs={formRefs}
  fieldValues={user.fieldValues} // We expect the user response from host's backend to send associated field_values with it.
  resourceId={user?.id}
  resourceType="users"
  onMutationSuccess={() => queryClient.invalidateQueries(["users"])}
  customComponents={{
    hostSpecificKindName: field => <HostSpecificInputFields />,
  }}
/>;

4. FieldInputs

FieldInputs image

The FieldInputs component render the input UI for the fetched fields. It accepts the following props:

Props:
  1. fields: An array of all the fetched fields.
  2. customComponents: If the host application has any extra kind other than the supported ones, you can specify the component to be displayed corresponding to that kind using this prop. It takes the kind name as the key and the component rendering callback function as the value. The callback function can expect the field object.
  3. formRefs: A React Ref object that can be used to access the Formik context of the form.
  4. disabled: Boolean value to specify whether to disable all fields.
  5. isRequiredColumnName: The name of column which holds the value which suggests if a field value is a required one or not.

:memo: Note:

To initialize the values for this formik fields, you need to use mergeInitialValues function.

To submit the values from this formik form, you need to use transformValues function to capture the right data from neeto-fields.

Usage:
import {
  FieldInputs,
  useFetchFields,
  neetoFieldsUtils,
} from "@bigbinary/neeto-fields-frontend";

const formRef = useRef();

const HostForm = () => {
  const {
    data: { fields },
  } = useFetchFields({
    resourceType: "users",
  });

  const initialValues = neetoFieldsUtils.mergeInitialValues({
    initialValues: INITIAL_VALUES,
    fields,
  });
  return (
    <Form
      formikProps={{
        initialValues,
        validationSchema: VALIDATION_SCHEMA,
        onSubmit: values =>
          onSubmit(neetoFieldsUtils.transformValues({ values, fields })),
        enableReinitialize: true,
      }}
    >
      {/* Other host specific input fields */}

      <FieldInputs formRef={formRef} fields={fields} />

      <Button type="submit" label="Submit" />
    </Form>
  );
};

Functions

The package exports the neetoFieldsUtils, which contains two utility functions.

1. neetoFieldsUtils.mergeInitialValues

This function builds the initial values for the Formik form that wraps the <FieldInputs /> component.

Arguments:
  • initialValues: The initial value object without considering <FieldInputs />
  • fields: An array of all the fetched fields.
Usage:
import { useFetchFields } from "@bigbinary/neeto-fields-frontend";

const {
  data: { fields },
} = useFetchFields({ resourceType: "users" });

const initialValues = neetoFieldsUtils.mergeInitialValues({
  initialValues: FORMIK_INITIAL_VALUES,
  fields,
});

2. neetoFieldsUtils.transformValues

This function transforms the Formik form values and builds the values object including the data from <FieldInputs />. This transformed object can be passed to the onSubmit function of the Formik form.

Arguments:
  • values: The Formik form values.
Usage:
import { useFetchFields } from "@bigbinary/neeto-fields-frontend";

const {
  data: { fields },
} = useFetchFields({ resourceType: "users" });

<Form
  formikProps={{
    initialValues,
    validationSchema: VALIDATION_SCHEMA,
    onSubmit: values =>
      onSubmit(neetoFieldsUtils.transformValues({ values, fields })),
    enableReinitialize: true,
  }}
>
  {/* Form's children */}
</Form>;

Hooks

1. useFetchFields

This is a React Query hook for fetching all the fields.

Arguments:
  • resourceType: The resource_type of the fields to be fetched.
  • ownerId: The ID of the owner in case the owner is not an organization.
Usage:
const {
  data: { fields, count, activeFieldsCount, inactiveFieldsCount },
} = useFetchFields({
  resourceType: "users",
  ownerId: "ownerId",
});
2. useShowField

This is a React Query hook for fetching details of a field.

Argument
  • fieldId: The ID of field for fetching details.
  • ownerId: The ID of the owner in case the owner is not an organization.
Usage
const {
  data: { field },
} = useShowField({ fieldId, ownerId });
3. useCreateField

This is a React Query hook for creating a field.

Usage
const { mutate: create } = useCreateField();
const payload = {
  field: { name, kind, resourceType, ownerId, displayOrder, data },
};
create(payload);
4. useUpdateField

This is a React Query hook for updating a field.

Usage
const { mutate: update } = useUpdateField();
const payload = {
  field: { name, kind, resourceType, ownerId, displayOrder, data },
};
update({ fieldId, payload });
5. useDestroyField

This is a React Query hook for deleting a field.

Usage
const { mutate: delete } = useDestroyField();
delete({ fieldId })

Pass the ownerId too with the payload in case the owner is not an organization.

Customizability

Engine customizability

In order to customize the engine's default behavior, we have several ways.

  • For improving the customizability, we've made every actions' duties into separate services, which can be overridden from the host apps as and when required.
  • If you wish to perform anything before or after the core logic of an action, we have provision to do it as a single transaction.
  • Every action has before_{action}_process method invoked before the core action logic and after_{action}_process method invoked after the core action logic.
  • These methods can be overridden by defining them in the concern NeetoFieldsEngine::Fields::Customizable or NeetoFieldsEngine::FieldValues::Customizable depending on the context.

Eg: If you want to do something before update action of FieldsController, then define it in before_update_process method inside the NeetoFieldsEngine::Fields::Customizable concern.

Development instructions

Engine development

  1. Add this line to your application's Gemfile (replace the path to the local copy of neeto-fields-engine):

    gem 'neeto-fields-engine', path: '../neeto-fields-engine'
    
  2. And then execute:

    bundle install
    
  3. Refer engine installation steps 3 and onwards.

Frontend package development

The usage of yalc is explained in this video: https://www.youtube.com/watch?v=QBiYGP0Rhe0

  1. See the changes in the host app by executing the following command

    Use this command if releasing package for the first time.

    yarn build && yalc publish
    

    Use this command to see changes after the initial publish.

    yarn release
    

Setup dummy host app

Setup Instructions.

Visit http://spinkart.lvh.me:9100 and login with email oliver@example.com and password welcome.

Additional instructions

  • Run yarn build to bundle the app.

Read about building and releasing

FAQs

Package last updated on 25 Aug 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc