diff --git a/studio/schemas/documents/compensations.ts b/studio/schemas/documents/compensations.ts index 33e828c67..881bea522 100644 --- a/studio/schemas/documents/compensations.ts +++ b/studio/schemas/documents/compensations.ts @@ -2,9 +2,9 @@ import { defineField, defineType } from "sanity"; import { titleSlug } from "../schemaTypes/slug"; import seo from "../objects/seo"; import { title } from "../fields/text"; -import { benefitId } from "./benefit"; import { bonusesByLocation } from "../objects/compensations/bonusesByLocation"; import { pension } from "../objects/compensations/pension"; +import { benefitsByLocation } from "../objects/compensations/benefitsByLocation"; export const compensationsId = "compensations"; @@ -30,38 +30,8 @@ const compensations = defineType({ }), pension, bonusesByLocation, + benefitsByLocation, // add salary here - // benefits should be updated to match the grouping by location: - // defineField({ - // name: "benefits", - // title: "Benefits", - // type: "array", - // of: [ - // defineField({ - // name: "benefitGroup", - // title: "Benefit Group", - // type: "object", - // fields: [ - // locations, - // defineField({ - // name: "benefitsList", - // title: "List of Benefits", - // type: "array", - // of: [{ type: benefitId }], - // }), - // ], - // }), - // ], - // }), - // IMPORTANT: this is just a very simple mockup and might not represent a good ux - defineField({ - name: "benefits", - title: "Included Benefits", - description: - "Add and manage information on the benefits included with the compensation package, such as health insurance, retirement plans, and paid time off.", - type: "array", - of: [{ type: benefitId }], - }), seo, ], preview: { diff --git a/studio/schemas/objects/compensations/benefitsByLocation.ts b/studio/schemas/objects/compensations/benefitsByLocation.ts new file mode 100644 index 000000000..cf06767f1 --- /dev/null +++ b/studio/schemas/objects/compensations/benefitsByLocation.ts @@ -0,0 +1,62 @@ +import { defineField } from "sanity"; +import { location, locationID } from "../locations"; +import { companyLocationNameID } from "studio/schemas/documents/companyLocation"; +import { benefitId } from "studio/schemas/documents/benefit"; +import { + checkForDuplicateLocations, + DocumentWithLocation, +} from "./utils/validation"; + +export const benefitsByLocation = defineField({ + name: "benefitsByLocation", + title: "Benefits by Location", + description: + "Specify the benefits offered at each office location. A benefit is only associated with a single location", + type: "array", + of: [ + { + type: "object", + fields: [ + { + ...location, + description: + "Select the office location for which you are entering benefits information. Each location must be unique.", + validation: (Rule) => Rule.required(), + }, + defineField({ + name: "benefitsGroup", + title: "Benefits Group", + description: + "Enter the benefits offered at the location selected above.", + type: "array", + of: [{ type: benefitId }], + }), + ], + preview: { + select: { + location: `${locationID}.${companyLocationNameID}`, + benefitsGroup: "benefitsGroup", + }, + prepare({ location, benefitsGroup }) { + const benefitsCount = benefitsGroup ? benefitsGroup.length : 0; + return { + title: location + ? `Benefits group for ${location}` + : "No location selected", + subtitle: `Number of benefits: ${benefitsCount}`, + }; + }, + }, + }, + ], + validation: (Rule) => + Rule.custom((benefitsByLocation) => { + const isNotDuplicate: boolean = checkForDuplicateLocations( + benefitsByLocation as DocumentWithLocation[] | undefined, + ); + return ( + isNotDuplicate || + "Each location should be listed only once in the benefits list." + ); + }), +}); diff --git a/studio/schemas/objects/compensations/utils/validation.ts b/studio/schemas/objects/compensations/utils/validation.ts new file mode 100644 index 000000000..3f1bd0796 --- /dev/null +++ b/studio/schemas/objects/compensations/utils/validation.ts @@ -0,0 +1,27 @@ +interface LocationReference { + _ref: string; + _type: string; + title?: string; +} + +export interface DocumentWithLocation { + location: LocationReference; +} + +/** + * Checks for duplicate location references in the documents array. + * Ensures each location has a unique document entry. + * + * @param {DocumentWithLocation[] | undefined} documents - The array of documents, each with one or more locations. + * @returns {string | true} - Returns an error message if duplicate locations are found, or true if all are unique. + */ +export const checkForDuplicateLocations = ( + documents: DocumentWithLocation[] | undefined, +): boolean => { + if (!documents) return true; + const locationRefs = documents + .map((entry) => entry.location?._ref) + .filter(Boolean); + const uniqueRefs = new Set(locationRefs); + return uniqueRefs.size === locationRefs.length; +};