Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 - per location compensations #540

Merged
merged 10 commits into from
Sep 3, 2024
54 changes: 54 additions & 0 deletions studio/schemas/documents/compensations.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import { defineField, defineType } from "sanity";
import { titleSlug } from "../schemaTypes/slug";
import seo from "../objects/seo";
import locations from "../objects/locations";
import { title } from "../fields/text";
import { benefitId } from "./benefit";

// maximum number of locations to display in the preview without truncating
const LOCATIONS_PREVIEW_CUTOFF = 3;

export const compensationsId = "compensations";

const compensations = defineType({
name: compensationsId,
type: "document",
title: "Compensations",
fields: [
locations,
title,
titleSlug,
seo,
Expand All @@ -29,6 +34,55 @@ const compensations = defineType({
of: [{ type: benefitId }],
}),
],
preview: {
select: {
title: "basicTitle",
/*
Access array object values using dot notation with the array index, e.g., "locations.0.basicTitle".
This approach allows selecting a subset of the array for preview purposes.
For more details, see: https://www.sanity.io/docs/previews-list-views#62febb15a63a
*/
mathiazom marked this conversation as resolved.
Show resolved Hide resolved
...[...Array(LOCATIONS_PREVIEW_CUTOFF + 1).keys()].reduce(
(o, i) => ({ ...o, [`location${i}`]: `locations.${i}.basicTitle` }),
{},
),
},
prepare({ title, ...locationsMap }) {
return {
title,
subtitle: previewStringFromLocationsMap(
locationsMap,
LOCATIONS_PREVIEW_CUTOFF,
),
};
},
},
});

mathiazom marked this conversation as resolved.
Show resolved Hide resolved
/**
* Generates a preview string based on the selected office locations.
*
* @param {Object} locationsMap - A map of office titles selected for preview, e.g., { office0: "Trondheim", office1: "Oslo", ... }.
* @param {number} cutoff - The maximum number of locations to display before shortening the preview string.
* @returns {string|undefined} - A formatted string summarizing the selected locations or `undefined` if no locations are selected.
*/
function previewStringFromLocationsMap(
locationsMap: {
[key: string]: string;
},
cutoff: number,
): string | undefined {
const locations = Object.values<string>(locationsMap).filter(
(o) => o !== undefined,
);
if (locations.length === 0) {
return undefined;
} else if (locations.length === 1) {
return `Location: ${locations[0]}`;
} else if (locations.length > cutoff) {
return `Locations: ${locations.toSpliced(cutoff - 1).join(", ")}, and more`;
}
return `Locations: ${locations.toSpliced(-1).join(", ")} and ${locations.at(-1)}`;
}

export default compensations;
22 changes: 22 additions & 0 deletions studio/schemas/objects/locations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineField } from "sanity";
import { locationId } from "../documents/location";

const locations = defineField({
name: "locations",
type: "array",
title: "Relevant Locations",
description:
"You can tailor this content to specific office locations by selecting them here. If the content applies to all locations, just leave this field empty.",
of: [
{
title: "Select a location",
type: "reference",
to: [{ type: locationId }],
options: {
disableNew: true,
},
},
],
});

export default locations;