انتقل إلى المحتوى الرئيسي

فترات الزمن

سمة timeInterval هي قاعدة تكرار، وليست قائمة من الفتحات: تاريخ مرجعي، نطاقات زمنية يومية وعلامات تكرار. قم بتحويلها إلى أزواج [start, end] ملموسة للنطاق الذي تقوم بعرضه فعليًا باستخدام المساعدات العليا expandAttributeTimeIntervals، expandTimeIntervals وحارس النوع isTimeIntervalAttribute.

import { expandAttributeTimeIntervals } from 'oneentry';

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});
// [['2025-04-14T09:00:00.000Z', '2025-04-14T10:00:00.000Z'], …]

جميع المساعدات الثلاثة هي نقية — فهي لا تغير مدخلاتها ولا تقوم بأي طلبات.

أين تعيش الجداول الزمنية

ترجع واجهة برمجة التطبيقات الجداول الزمنية بشكلين، وكلاهما مقبول من قبل المساعدات:

الشكلأين تجدهاتحمل
الكيان (ITimeIntervalEntitySchedule)attributeValues[marker].value[].values[] على الصفحات، المنتجات، الكتل ومجموعات السماتنطاق dates مع أزواج times
النموذج (ITimeIntervalSchedule)attributes[].localizeInfos.intervals[] على النماذجنطاق مع intervals تحمل فترة فتحة بالدقائق

expandAttributeTimeIntervals(attr, window)

المسار ذو الاستدعاء الواحد لسمات الكيانات: يتجول في مجموعات السمة والجداول الزمنية، ويوسع كل منها ويمزج النتائج. المزج مهم — فإزالة التكرار والترتيب يحدثان فقط ضمن جدول زمني واحد، لذا فإن دمج المجموعات يدويًا يمكن أن يؤدي إلى فتحات مكررة أو غير مرتبة.

أي شيء ليس سمة timeInterval ينتج مصفوفة فارغة، لذا من الآمن استدعاؤه دون التحقق من type أولاً.

import { expandAttributeTimeIntervals } from 'oneentry';

const page = await Pages.getPageByUrl('booking');

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

expandTimeIntervals(schedule, window)

يحل جدولًا زمنيًا واحدًا. استخدمه عندما يكون لديك واحد بالفعل — وخاصة على النماذج، التي تكون جداولها الزمنية مكتوبة بالفعل في localizeInfos.intervals:

import { expandTimeIntervals } from 'oneentry';

const form = await Forms.getFormByMarker('booking_form');
const field = form.attributes.find((a) => a.marker === 'schedule');

const slots = (field?.localizeInfos.intervals ?? []).flatMap((schedule) =>
expandTimeIntervals(schedule, { from: '2025-05-01', to: '2025-05-31' }),
);

isTimeIntervalAttribute(attr)

IAttributeValue.value مكتوب كـ unknown، لأن شكله يعتمد على type. يقوم حارس النوع هذا بتضييق السمة إلى ITimeIntervalAttributeValue، مما يتيح لك الوصول إلى الجداول الزمنية دون تحويل:

import { isTimeIntervalAttribute } from 'oneentry';

const attr = page.attributeValues.interval;

if (isTimeIntervalAttribute(attr)) {
attr.value[0].values[0].dates; // fully typed
}

النافذة

const window = { from: '2025-04-01', to: '2025-04-30' };
  • from و to تقبلان Date، سلسلة ISO أو ميلي ثانية من العصر.
  • كلا الحدين شاملين ويتم مقارنتهما بدقة يوم UTC — يتم تجاهل جزء الوقت من from/to.
  • النافذة مطلوبة: الجدول الزمني هو قاعدة تكرار مفتوحة، فقط أنت تعرف إلى أي مدى يجب أن يتم حله.

دلالات التكرار

  • dates[0] / range[0] هو كل من مرحلة التكرار وأول يوم صالح — لا يتم إصدار أي شيء سابق، مهما كان عرض النافذة.
  • dates[1] / range[1] ينهي الصلاحية. عندما لا يمتد بعد البداية، يكون الجدول الزمني مرتبطًا بذلك اليوم الواحد؛ مع تعيين علامة التكرار، يكون التكرار مفتوحًا والنافذة وحدها تحدد النتيجة.
  • inEveryWeek يتكرر كل 7 أيام من المرجع.
  • inEveryMonth يتكرر في نفس اليوم من الشهر، متجاوزًا الأشهر القصيرة جدًا.
  • مع تعيين كلا العلامتين، تنطبق القاعدة الأسبوعية — وهو ما كان يعنيه دائمًا في الممارسة.
  • مع عدم تعيين أي علامة، يكون الجدول الزمني نطاق تاريخ عادي: كل يوم منه ينتج فتحات.
  • يتم إزالة التكرار وترتيب النتيجة حسب البداية، ثم حسب النهاية.
  • جميع العمليات الحسابية هي بتوقيت UTC، لذا فإن النتيجة لا تعتمد على منطقة زمنية الجهاز.

الانتقال من حقل timeIntervals

كانت إصدارات SDK السابقة تضيف مصفوفة timeIntervals المحسوبة إلى كل قيمة سمة timeInterval. هذا الحقل لم يعد موجودًا. لقد أظهر مجموعة كاملة من الفتحات بغض النظر عما يحتاجه المتصل — سمة واحدة مع فتحات ساعة تم توسيعها إلى حوالي 2,000 سطر من JSON، وكانت فترات الفتحات الأكثر دقة تصل إلى ميغابايت، مما يكفي لتجاوز حدود ذاكرة التخزين المؤقت للبيانات في الإطار. لم يتم الإعلان عنها في أي واجهة أو مخطط أيضًا، لذا كان بإمكان مستهلكي TypeScript الوصول إليها فقط من خلال تحويل.

// before — read the pre-computed field
const slots = page.attributeValues.interval.value[0].values[0].timeIntervals;

// now — expand the window you actually render
import { expandAttributeTimeIntervals } from 'oneentry';

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

تظل البيانات المصدر التي يتم توسيعها (dates/range، times/intervals، inEveryWeek، inEveryMonth) دون تغيير وما زالت موجودة في كل جدول زمني — لا شيء مفقود، بل يتم حله عند الطلب بدلاً من التوسع بشكل متعجل، والقاعدة المدمجة هي ما يتم تخزينه في الذاكرة المؤقتة.

تمت إزالة طرق _addTimeIntervalsToSchedules و _addTimeIntervalsToFormSchedules من كل وحدة أيضًا (على الرغم من أن البادئة _ كانت قابلة للاستدعاء، مثل Pages._addTimeIntervalsToSchedules). استخدم expandTimeIntervals بدلاً من ذلك.

الأنواع

جميع هذه الأنواع مستخرجة من جذر الحزمة ومن oneentry/types (انظر استيراد الأنواع):

النوعيصف
ITimeIntervalAttributeValueقيمة IAttributeValue مضيقة إلى type: 'timeInterval'، التي تكون value لها مصفوفة من المجموعات
ITimeIntervalGroupإدخال واحد من value للسمة — جداول تشترك في intervalId
ITimeIntervalEntityScheduleجدول زمني واحد للكيان: dates، times، inEveryWeek، inEveryMonth
ITimeIntervalScheduleجدول زمني واحد للنموذج: range، intervals، inEveryWeek، inEveryMonth
ITimeIntervalRangeنطاق يومي مع start، end وفترة فتحة بالدقائق (null عند عدم تقسيمها)
ITimeIntervalPointنقطة في اليوم - { hours, minutes }
ITimeIntervalWindowنافذة التوسع - { from, to }
TimeIntervalPairفتحة واحدة تم حلها - [start, end]، كلاهما سلاسل ISO 8601 UTC

مثال: عرض شهر من الفتحات

import { expandAttributeTimeIntervals } from 'oneentry';

const page = await Pages.getPageByUrl('booking');

if ('statusCode' in page) {
throw new Error(page.message);
}

const slots = expandAttributeTimeIntervals(page.attributeValues.interval, {
from: '2025-04-01',
to: '2025-04-30',
});

// Group the slots by day for a calendar view
const byDay = slots.reduce((acc, [start, end]) => {
const day = start.slice(0, 10);
(acc[day] ??= []).push([start, end]);
return acc;
}, {});

🔗 الوثائق ذات الصلة