Skip to content

Commit

Permalink
v3 - per location compensations (#540)
Browse files Browse the repository at this point in the history
* feat(compensations): offices reference

* feat(compensations): offices array preview

* docs(compensations): improve array preview comment

* feat(compensations): move offices string to preview subtitle and reformat

* feat(compensations): helper description for offices field

* feat(office): default descriptions for reusable office and offices fields

* feat(compensations): rename office -> locations

* docs(compensations): remove explainer for preview truncation cutoff

* docs(compensations): document preview string function

* docs(compensations): reword locations preview comment
  • Loading branch information
mathiazom authored Sep 3, 2024
1 parent 5a69f3e commit e2c9d25
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
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
*/
...[...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,
),
};
},
},
});

/**
* 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;

0 comments on commit e2c9d25

Please sign in to comment.