sanity-io / sanity

Sanity Studio – Rapidly configure content workspaces powered by structured content
https://www.sanity.io
MIT License
5.18k stars 417 forks source link

[v3] document ordering by datetime field type doesn't order correctly #3985

Open genox opened 1 year ago

genox commented 1 year ago

I define a field like this:

    defineField({
      title: 'Date of publication',
      name: 'published',
      type: 'datetime',
      initialValue: new Date().toISOString(),
      validation: (Rule) => Rule.required(),
    }),

And I would like to order documents in the studio panel like this:

  orderings: [
    {
      title: 'Published, new first',
      name: 'publishedDesc',
      by: [{ field: 'published', direction: 'desc' }],
    },
    {
      title: 'Published, old first',
      name: 'publishedAsc',
      by: [{ field: 'published', direction: 'asc' }],
    },
  ],

But the ordering is all over the place, I can't see any pattern. I remember having had the same issue a while back and there are a number of related issues already here, but they are for V2 and marked as fixed.

Side effect: when I switch from desc to asc, I get a loading spinner of death. There is no output on console.log and I don't see any pending requests.

V3 latest, Chrome, Mac

waspeer commented 4 months ago

This issue is pretty old, but I can confirm I'm encountering this as well when trying to do a custom sort order on a datetime field.

I'm on "sanity": "^3.40.0"

lightstrike commented 4 months ago

@waspeer Confirming I'm hitting this issue as well on Sanity v3. Let me know if you figure out any workaround.

naotone commented 1 month ago

"sanity":"^3.52.1", also has the same issue. To implement a temporary workaround, I have created a field for orders with type: string, ensuring the value is automatically populated.

defineField({
  name: 'publishedAt',
  title: 'Published at',
  type: 'datetime',
  validation: (Rule) => Rule.required(),
  initialValue: () => new Date().toISOString(),
}),
defineField({
  name: 'publishedAtOrder',
  title: 'Published at (Order)',
  type: 'string',
  readOnly: true,
  hidden: false, // Must be false to trigger sync
  components: {
    input: (props) => <SynchronizedDateInput {...props} />,
  },
  initialValue: () => new Date().toISOString().split('.')[0],
  validation: (Rule) => Rule.required(),
}),

SynchronizedDateInput.tsx

import { TextInput } from '@sanity/ui';
import { useEffect } from 'react';
import { set, useFormValue, type InputProps } from 'sanity';

const SynchronizedDateInput = (props: InputProps) => {
  const { onChange, value } = props;
  const publishedAt = useFormValue(['publishedAt']) as string;

  useEffect(() => {
    if (publishedAt !== value) {
      try {
        const formattedDateTime = new Date(publishedAt).toISOString().split('.')[0];
        onChange(set(formattedDateTime));
      } catch (err) {
        console.error('Error processing publishedAt:', err, { publishedAt });
      }
    }
  }, [publishedAt, onChange, value]);

  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    onChange(set(event.target.value));
  };
  return (
    <TextInput value={value as string} onChange={handleInputChange}  />
  )};

export default SynchronizedDateInput;

sanity.custom.css To hide the publishedAtOrder field

div[data-comments-field-id='publishedAtOrder'] {
  display: none !important;
}