joas8211 / payload-tenancy

Multi-tenancy plugin for Payload CMS
MIT License
122 stars 6 forks source link

Make it easier to modify fields #8

Open joas8211 opened 1 year ago

joas8211 commented 1 year ago

Currently fields added by this plugin cannot be modified by the project using the plugin. Only plugins that are applied after this plugin can currently modify the fields.

It should be to be possible to define fields in project's config by using same names as fields in this plugin is using and override properties that way.

Example

// Plugin adds following field:
const pluginTenantSlugField = {
  type: "text",
  name: "slug",
  unique: true,
  required: true,
};

// Field can be extended by defining the field in project's config:
const projectConfig = {
  collections: [
    {
      slug: "tenants",
      fields: [
        {
          type: "text",
          name: "slug",
          beforeValidate: ({ value }) => {
            if (!value || typeof value !== "string") {
              return "";
            }

            // Format slug.
            return value
              .trim()
              .toLowerCase()
              .replace(/[^\w\s-]/g, "")
              .replace(/\s+/g, "-")
              .replace(/--+/g, "-")
              .replace(/^-+|-+$/g, "");
          },
        },
      ],
    },
  ],
};

// Resulting field uses the project's field if possible and applies missing
// properties from plugin's field. Or uses the plugin's field if project does
// not have a field with the same name.
const projectTenantSlugField = tenantCollection.fields.find(
  (field) => field.name === "slug"
);
const resultingField = { ...pluginTenantSlugField, ...projectTenantSlugField };

The above way of merging works for this case but it might be neccessary to implement a merge function that handles nested objects.

joas8211 commented 1 year ago

I think this still needs some work so that individual properties like validation functions can be extended easily.