Skip to content

Commit

Permalink
v3 - custom ordered array input component (#683)
Browse files Browse the repository at this point in the history
* feat(compensations): custom component for fixed order of array input elements

* refactor(ValueOrderedArrayOfObjectsInput): OrderedArrayOfObjectsInputProps → ValueOrderedArrayOfObjectsInputProps
  • Loading branch information
mathiazom authored Sep 27, 2024
1 parent 6ae8f10 commit b18fae3
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 13 deletions.
29 changes: 29 additions & 0 deletions studio/components/ValueOrderedArrayOfObjectsInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ArrayOfObjectsInputProps, ObjectItem } from "sanity";

interface ValueOrderedArrayOfObjectsInputProps
extends ArrayOfObjectsInputProps {
valueCompareFn: (a: ObjectItem, b: ObjectItem) => number;
}

export default function ValueOrderedArrayOfObjectsInput({
valueCompareFn,
...defaultProps
}: ValueOrderedArrayOfObjectsInputProps) {
const orderedMembers = defaultProps.members.toSorted((a, b) => {
// place error items at the end
if (a.kind === "error") {
if (b.kind === "error") {
return 0;
} else {
return 1;
}
} else if (b.kind === "error") {
return -1;
}
return valueCompareFn(a.item.value, b.item.value);
});
return defaultProps.renderDefault({
...defaultProps,
members: orderedMembers,
});
}
36 changes: 32 additions & 4 deletions studio/lib/interfaces/compensations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PortableTextBlock } from "sanity";
import { PortableTextBlock, Reference } from "sanity";

import { Reference, Slug } from "./global";
import { Slug } from "./global";

export interface Benefit {
_type: string;
Expand All @@ -16,12 +16,26 @@ export interface BenefitsByLocation {
}

export interface SalariesPage {
_type: string;
_type?: string;
_key: string;
year: number;
salaries: string;
}

export const isSalariesPage = (value: unknown): value is SalariesPage => {
return (
typeof value === "object" &&
value !== null &&
(!("_type" in value) || typeof value._type === "string") &&
"_key" in value &&
typeof value._key === "string" &&
"year" in value &&
typeof value.year === "number" &&
"salaries" in value &&
typeof value.salaries === "string"
);
};

export interface BonusesByLocationPage {
_type: string;
_key: string;
Expand All @@ -30,12 +44,26 @@ export interface BonusesByLocationPage {
}

export interface BonusPage {
_type: string;
_type?: string;
_key: string;
year: number;
bonus: number;
}

export const isBonusPage = (value: unknown): value is BonusPage => {
return (
typeof value === "object" &&
value !== null &&
(!("_type" in value) || typeof value._type === "string") &&
"_key" in value &&
typeof value._key === "string" &&
"year" in value &&
typeof value.year === "number" &&
"bonus" in value &&
typeof value.bonus === "number"
);
};

export interface SalariesByLocation {
_key: string;
_type: string;
Expand Down
5 changes: 0 additions & 5 deletions studio/lib/interfaces/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ export interface Slug {
current: string;
}

export interface Reference {
_type: "reference";
_ref: string;
}

export interface DocumentWithSlug {
slug: Slug;
_updatedAt: string;
Expand Down
25 changes: 23 additions & 2 deletions studio/schemas/objects/compensations/bonusesByLocation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineField } from "sanity";
import { ArrayOfObjectsInputProps, defineField } from "sanity";

import { BonusPage } from "studio/lib/interfaces/compensations";
import ValueOrderedArrayOfObjectsInput from "studio/components/ValueOrderedArrayOfObjectsInput";
import { BonusPage, isBonusPage } from "studio/lib/interfaces/compensations";
import { companyLocationNameID } from "studio/schemas/documents/admin/companyLocation";
import { location, locationID } from "studio/schemas/objects/locations";

Expand Down Expand Up @@ -35,6 +36,26 @@ export const bonusesByLocation = defineField({
description:
"Bonus data reflecting the bonus given to employees for a given year.",
type: "array",
options: {
sortable: false,
},
components: {
input: (props: ArrayOfObjectsInputProps) =>
ValueOrderedArrayOfObjectsInput({
...props,
valueCompareFn: (a, b) => {
if (isBonusPage(a)) {
if (isBonusPage(b)) {
return b.year - a.year;
}
return -1;
} else if (isBonusPage(b)) {
return 1;
}
return 0;
},
}),
},
of: [
{
type: "object",
Expand Down
28 changes: 26 additions & 2 deletions studio/schemas/objects/compensations/salariesByLocation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { defineField } from "sanity";
import { ArrayOfObjectsInputProps, defineField } from "sanity";

import { SalariesInput } from "studio/components/salariesInput/SalariesInput";
import { SalariesPage } from "studio/lib/interfaces/compensations";
import ValueOrderedArrayOfObjectsInput from "studio/components/ValueOrderedArrayOfObjectsInput";
import {
SalariesPage,
isSalariesPage,
} from "studio/lib/interfaces/compensations";
import { companyLocationNameID } from "studio/schemas/documents/admin/companyLocation";
import { location, locationID } from "studio/schemas/objects/locations";

Expand Down Expand Up @@ -34,6 +38,26 @@ export const salariesByLocation = defineField({
description:
"Salary data reflecting salaries given to employees for a given year. ",
type: "array",
options: {
sortable: false,
},
components: {
input: (props: ArrayOfObjectsInputProps) =>
ValueOrderedArrayOfObjectsInput({
...props,
valueCompareFn: (a, b) => {
if (isSalariesPage(a)) {
if (isSalariesPage(b)) {
return b.year - a.year;
}
return -1;
} else if (isSalariesPage(b)) {
return 1;
}
return 0;
},
}),
},
of: [
{
type: "object",
Expand Down

0 comments on commit b18fae3

Please sign in to comment.