![Maven Central Adds Sigstore Signature Validation](https://cdn.sanity.io/images/cgdhsj6q/production/7da3bc8a946cfb5df15d7fcf49767faedc72b483-1024x1024.webp?w=400&fit=max&auto=format)
Security News
Maven Central Adds Sigstore Signature Validation
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
@bigbinary/neeto-fields-frontend
Advanced tools
A repo acts as the source of truth for the new nano's structure, configs, data etc.
neeto-fields-nano enables the management of dynamically added fields (often referred as custom fields) for the resources across neeto products.
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
.
Add this line to your application's Gemfile:
source "NEETO_GEM_SERVER_URL" do
# ..existing gems
gem 'neeto-fields-engine'
end
And then execute:
bundle install
Add this line to your application's config/routes.rb
file
mount NeetoFieldsEngine::Engine => "/neeto_fields_engine"
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).
rails db:migrate
rails g neeto_fields_engine:associations
This will prompt the user to enter 2 things:
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.
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.
FieldsDashboard
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.
rowData
: Represents the rowData for the table within the dashboard.
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.
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.
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
.
allowedKinds
:Specifies the list of field kinds allowed to be created.
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).showStateFilter
: Boolean value which specifies whether to show or hide
state filters.
fieldStatesTaxonomy
: Specifies the names to be rendered for active
and
inactive
states.
breadcrumbs
: Specifies the breadcrumbs to be displayed on the dashboard
page.
helpDocUrl
: Specify the URL to the help documentation about fields. This
URL will be shown in the NoData
screen.
nameAliases
: This property accepts alias names as key-value pairs to be
displayed for the names of resource types in header and menubar.
headerTitle
: Specify the header title explicitly. Default is 'fields'
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.
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",
},
]}
/>;
FieldsPane
This is the pane which handles the Add / Edit operations of the field.
isOpen
: Boolean state which specifies the open/close state of the pane.onClose
: The function to be executed on closing the pane.resourceType
: Specifies the resource_type of the field to be created via
the pane.allowedKinds
: Specifies the list of field kinds allowed to be created.children
: Children components for the pane.additionalValidations
: Validations for the formik fields in children
.initialValues
: Initial values for the formik fields in children
.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.hideRequiredSwitch
: Specify whether to hide the Is required
toggle switch
for field in pane.ownerId
: The ID of the owner in case the owner is not an organization.onMutationSuccess
: The callback function which is triggered on the success
of mutation functions( create, update & delete).import { AddField } from "@biginary/neeto-fields-frontend";
<AddField
allowedKinds={["text", "number"]}
resourceType="users"
additionalValidations={{
hostSpecificInputName: validationSchema,
}}
initialValues={{ hostSpecificInputName: initialValue }}
>
<HostSpecificInputFields />
</AddField>;
FieldValuesContainer
The FieldValuesContainer
component handles field values associated with a
specific resource.
resourceType
: The type of resource.fieldValues
: Field values associated with the resource obtained from the
response.fields
: Fields associated with resource type. This is an optional prop. If
not provided the component will fetch the fields internally.resourceId
: The ID of the resource.ownerId
:The ID of the owner. This prop is required only if the owner is not
an organization.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.className
: Class names for styling.showBorder
: Boolean value to specify whether to show or hide borders.
Default true.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.disabled
: Boolean value to specify whether to disable all fields.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.fieldContainerClassName
: Class names for styling the div
containing the
input field.fieldClassName
: Class names for styling the field.labelClassName
: Class names for styling the label for fields.onMutationSuccess
: The callback function which is triggered on the success
of mutation functions( create, update & delete).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 />,
}}
/>;
FieldInputs
The FieldInputs component render the input UI for the fetched fields. It accepts the following props:
fields
: An array of all the fetched fields.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.formRefs
: A React Ref object that can be used to access the Formik context
of the form.disabled
: Boolean value to specify whether to disable all fields.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.
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>
);
};
The package exports the neetoFieldsUtils
, which contains two utility
functions.
neetoFieldsUtils.mergeInitialValues
This function builds the initial values for the Formik form that wraps the
<FieldInputs />
component.
initialValues
: The initial value object without considering
<FieldInputs />
fields
: An array of all the fetched fields.import { useFetchFields } from "@bigbinary/neeto-fields-frontend";
const {
data: { fields },
} = useFetchFields({ resourceType: "users" });
const initialValues = neetoFieldsUtils.mergeInitialValues({
initialValues: FORMIK_INITIAL_VALUES,
fields,
});
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.
values
: The Formik form values.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>;
useFetchFields
This is a React Query hook for fetching all the fields.
resourceType
: The resource_type of the fields to be fetched.ownerId
: The ID of the owner in case the owner is not an organization.const {
data: { fields, count, activeFieldsCount, inactiveFieldsCount },
} = useFetchFields({
resourceType: "users",
ownerId: "ownerId",
});
useShowField
This is a React Query hook for fetching details of a field.
fieldId
: The ID of field for fetching details.ownerId
: The ID of the owner in case the owner is not an organization.const {
data: { field },
} = useShowField({ fieldId, ownerId });
useCreateField
This is a React Query hook for creating a field.
const { mutate: create } = useCreateField();
const payload = {
field: { name, kind, resourceType, ownerId, displayOrder, data },
};
create(payload);
useUpdateField
This is a React Query hook for updating a field.
const { mutate: update } = useUpdateField();
const payload = {
field: { name, kind, resourceType, ownerId, displayOrder, data },
};
update({ fieldId, payload });
useDestroyField
This is a React Query hook for deleting a field.
const { mutate: delete } = useDestroyField();
delete({ fieldId })
Pass the ownerId
too with the payload in case the owner is not an
organization.
In order to customize the engine's default behavior, we have several ways.
before_{action}_process
method invoked before the core
action logic and after_{action}_process
method invoked after the core action
logic.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 inbefore_update_process
method inside theNeetoFieldsEngine::Fields::Customizable
concern.
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'
And then execute:
bundle install
Refer engine installation steps 3 and onwards.
The usage of yalc
is explained in this video:
https://www.youtube.com/watch?v=QBiYGP0Rhe0
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 Instructions.
Visit http://spinkart.lvh.me:9100 and login with email oliver@example.com
and
password welcome
.
yarn build
to bundle the app.FAQs
A repo acts as the source of truth for the new nano's structure, configs, data etc.
The npm package @bigbinary/neeto-fields-frontend receives a total of 0 weekly downloads. As such, @bigbinary/neeto-fields-frontend popularity was classified as not popular.
We found that @bigbinary/neeto-fields-frontend demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
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.
Security News
Maven Central now validates Sigstore signatures, making it easier for developers to verify the provenance of Java packages.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.