@object-ui/plugin-timeline 17.3.0 → 17.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +400 -0
- package/README.md +0 -11
- package/dist/ObjectTimeline.d.ts +35 -0
- package/dist/ObjectTimeline.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +151 -135
- package/dist/index.umd.cjs +1 -1
- package/dist/renderer.d.ts +19 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/useTimelineTranslation.d.ts +25 -0
- package/dist/useTimelineTranslation.d.ts.map +1 -1
- package/package.json +10 -10
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/components"),require("react/jsx-runtime"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/mobile"),require("zod"),require("@object-ui/i18n")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/components`,`react/jsx-runtime`,`@object-ui/core`,`@object-ui/react`,`@object-ui/mobile`,`zod`,`@object-ui/i18n`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTimeline={},e.React,e.ObjectUIComponents,e.react_jsx_runtime,e.ObjectUICore,e.ObjectUIReact,e.ObjectUIMobile,e.zod,e._object_ui_i18n))})(this,function(e,t,n,r,i,a,o,s,c){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var l=Object.create,u=Object.defineProperty,d=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyNames,p=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty,h=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=f(t),a=0,o=i.length,s;a<o;a++)s=i[a],!m.call(e,s)&&s!==n&&u(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=d(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:l(p(e)),h(t||!e||!e.__esModule||!m.call(e,`default`)?u(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var g=new Set([`hour`,`day`,`week`,`month`,`quarter`,`year`]);function _(e){let t=e.scale??e.timeScale;return typeof t==`string`&&g.has(t)?t:`month`}function v(e,t,n){let r=[],i=new Date(t),a=new Date(n);if(Number.isNaN(i.getTime())||Number.isNaN(a.getTime())||i>a)return r;let o=new Date(i);switch(e){case`hour`:for(;o<=a;)r.push(o.toLocaleString(`en-US`,{month:`short`,day:`numeric`,hour:`numeric`})),o.setHours(o.getHours()+1);break;case`day`:for(;o<=a;)r.push(o.toLocaleDateString(`en-US`,{month:`short`,day:`numeric`})),o.setDate(o.getDate()+1);break;case`week`:{let e=1;for(;o<=a;)r.push(`Week ${e++}`),o.setDate(o.getDate()+7);break}case`quarter`:for(o.setMonth(Math.floor(o.getMonth()/3)*3,1);o<=a;)r.push(`Q${Math.floor(o.getMonth()/3)+1} ${o.getFullYear()}`),o.setMonth(o.getMonth()+3);break;case`year`:for(o.setMonth(0,1);o<=a;)r.push(String(o.getFullYear())),o.setFullYear(o.getFullYear()+1);break;default:for(;o<=a;)r.push(o.toLocaleDateString(`en-US`,{month:`short`,year:`numeric`})),o.setMonth(o.getMonth()+1)}return r}function y(e){let t=e.flatMap(e=>(e.items||[]).flatMap(e=>[e.startDate,e.endDate])),n=Math.min(...t.map(e=>new Date(e).getTime())),r=Math.max(...t.map(e=>new Date(e).getTime()));return{minDate:new Date(n).toISOString().split(`T`)[0],maxDate:new Date(r).toISOString().split(`T`)[0]}}function b(e,t,n,r){let i=new Date(e).getTime(),a=new Date(t).getTime(),o=new Date(n).getTime(),s=new Date(r).getTime()-o,c=i-o,l=a-i;return{start:c/s*100,width:l/s*100}}function x(e,t){let n=new Date(e);return t===`short`?n.toLocaleDateString():t===`long`?n.toLocaleDateString(`en-US`,{year:`numeric`,month:`long`,day:`numeric`}):n.toISOString().split(`T`)[0]}function S({label:e,color:t}){let i=t?{backgroundColor:`${t}22`,color:t,borderColor:`${t}55`}:void 0;return(0,r.jsx)(`span`,{className:(0,n.cn)(`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium`,!t&&`bg-muted text-muted-foreground border-transparent`),style:i,children:e})}function C(e){let t=[];for(let n of e){let e=n.group==null?``:String(n.group),r=t[t.length-1];r&&r.key===e?r.items.push(n):t.push({key:e,items:[n]})}return t}var w=({schema:e,className:t,...i})=>{let{variant:a=`vertical`,items:o=[],dateFormat:s=`short`,onItemClick:c}=e;if(a===`vertical`){let e=C(o),a=e.some(e=>e.key!==``),l=(e,t)=>{let i=e.color?{backgroundColor:`${e.color}33`,borderColor:e.color}:void 0,a=e.time?x(e.time,s):e.startDate?x(e.startDate,s):``,o=e.endDate&&e.endDate!==e.startDate?x(e.endDate,s):``,l=Array.isArray(e.meta)?e.meta:[];return(0,r.jsxs)(N,{density:`compact`,className:(0,n.cn)(e.className,c&&`cursor-pointer`),onClick:()=>c?.(e),children:[(0,r.jsx)(F,{variant:e.color?`default`:e.variant||`default`,style:i,children:e.icon&&(0,r.jsx)(`span`,{className:`text-xs`,children:e.icon})}),(0,r.jsxs)(I,{children:[(a||o)&&(0,r.jsxs)(R,{dateTime:e.time||e.startDate,className:`!mb-1 text-xs`,children:[a,o&&(0,r.jsxs)(`span`,{className:`text-muted-foreground/70`,children:[` → `,o]})]}),e.title&&(0,r.jsx)(L,{className:`text-sm sm:text-base mb-1`,children:e.title}),l.length>0&&(0,r.jsx)(`div`,{className:`flex flex-wrap gap-1.5 mt-1 mb-1`,children:l.map(e=>(0,r.jsx)(S,{label:e.label,color:e.color},e.key))}),e.description&&(0,r.jsx)(z,{className:`text-sm text-muted-foreground line-clamp-2 sm:line-clamp-none`,children:e.description}),e.content&&(0,n.renderChildren)(e.content)]})]},t)};return a?(0,r.jsx)(`div`,{className:(0,n.cn)(`px-4 sm:px-6 py-2`,t),...i,children:e.map((e,t)=>(0,r.jsxs)(`section`,{className:`mb-4`,children:[(0,r.jsxs)(`header`,{className:`sticky top-0 z-10 -mx-4 sm:-mx-6 px-4 sm:px-6 py-1.5 backdrop-blur bg-background/90 text-xs font-semibold uppercase tracking-wide text-muted-foreground border-b`,children:[(0,r.jsx)(`span`,{children:e.key}),(0,r.jsx)(`span`,{className:`ml-2 text-muted-foreground/60 font-normal normal-case`,children:e.items.length})]}),(0,r.jsx)(j,{className:`mt-3`,children:e.items.map((e,n)=>l(e,`${t}-${n}`))})]},`${e.key}-${t}`))}):(0,r.jsx)(j,{className:t,...i,children:o.map((e,t)=>l(e,t))})}if(a===`horizontal`)return(0,r.jsx)(B,{className:(0,n.cn)(`overflow-x-auto [-webkit-overflow-scrolling:touch]`,t),...i,children:o.map((e,t)=>(0,r.jsxs)(V,{className:(0,n.cn)(e.className,c&&`cursor-pointer`),onClick:()=>c?.(e),children:[(0,r.jsxs)(`div`,{className:`flex flex-col items-center`,children:[(0,r.jsx)(F,{variant:e.variant||`default`,children:e.icon&&(0,r.jsx)(`span`,{className:`text-xs`,children:e.icon})}),(0,r.jsxs)(`div`,{className:`mt-4 text-center`,children:[e.time&&(0,r.jsx)(R,{dateTime:e.time,children:x(e.time,s)}),e.title&&(0,r.jsx)(L,{children:e.title}),e.description&&(0,r.jsx)(z,{className:`text-center line-clamp-2 sm:line-clamp-none`,children:e.description}),e.content&&(0,n.renderChildren)(e.content)]})]}),t<o.length-1&&(0,r.jsx)(`div`,{className:`absolute left-full w-16 border-t-2 border-gray-200 top-3`})]},t))});if(a===`gantt`){let a=y(o),l=e.minDate||a.minDate,u=e.maxDate||a.maxDate,d=v(_(e),l,u);return(0,r.jsxs)(H,{className:(0,n.cn)(`overflow-x-auto [-webkit-overflow-scrolling:touch]`,t),...i,children:[(0,r.jsxs)(U,{children:[(0,r.jsx)(W,{className:`flex items-center px-2 sm:px-4 py-2 sm:py-3`,children:(0,r.jsx)(`span`,{className:`font-semibold text-xs sm:text-sm`,children:e.rowLabel||`Items`})}),(0,r.jsx)(G,{children:(0,r.jsx)(`div`,{className:`flex h-full`,children:d.map((e,t)=>(0,r.jsx)(`div`,{className:`flex-1 px-1 sm:px-2 py-2 sm:py-3 border-r text-xs font-medium text-center`,children:e},t))})})]}),(0,r.jsx)(`div`,{children:(0,r.jsxs)(`div`,{className:`flex`,children:[(0,r.jsx)(W,{children:o.map((e,t)=>(0,r.jsx)(K,{children:(0,r.jsx)(q,{title:e.label,className:`truncate`,children:e.label})},t))}),(0,r.jsx)(G,{className:`relative`,children:o.map((e,t)=>(0,r.jsx)(K,{className:`relative`,children:(e.items||[]).map((n,i)=>{let a=b(n.startDate,n.endDate,l,u);return(0,r.jsx)(J,{start:a.start,width:a.width,variant:n.variant||`default`,onClick:()=>c?.(n,e,t,i),title:`${n.title||``}\n${x(n.startDate,s)} - ${x(n.endDate,s)}`,children:(0,r.jsx)(Y,{children:n.title})},i)})},t))})]})})]})}return null};i.ComponentRegistry.register(`timeline`,w,{namespace:`plugin-timeline`,label:`Timeline`,category:`data-display`,inputs:[{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],label:`Timeline Variant`,defaultValue:`vertical`},{name:`items`,type:`array`,label:`Timeline Items`,description:`For vertical/horizontal: Array of { time, title, description, variant, icon, content }. For gantt: Array of { label, items: [{ title, startDate, endDate, variant }] }`},{name:`dateFormat`,type:`enum`,enum:[`short`,`long`,`iso`],label:`Date Format`,defaultValue:`short`},{name:`timeScale`,type:`enum`,enum:[`day`,`week`,`month`],label:`Time Scale (Gantt only)`,defaultValue:`month`},{name:`rowLabel`,type:`string`,label:`Row Label (Gantt only)`,defaultValue:`Items`},{name:`minDate`,type:`string`,label:`Min Date (Gantt only)`,description:`Override auto-calculated min date (YYYY-MM-DD)`},{name:`maxDate`,type:`string`,label:`Max Date (Gantt only)`,description:`Override auto-calculated max date (YYYY-MM-DD)`},{name:`className`,type:`string`,label:`CSS Class`}],defaultProps:{variant:`vertical`,dateFormat:`short`,items:[{time:`2024-01-15`,title:`Project Started`,description:`Kickoff meeting and initial planning`,variant:`success`,icon:`🚀`},{time:`2024-02-01`,title:`First Milestone`,description:`Completed initial design phase`,variant:`info`,icon:`🎨`},{time:`2024-03-15`,title:`Beta Release`,description:`Released beta version to testers`,variant:`warning`,icon:`⚡`},{time:`2024-04-01`,title:`Launch`,description:`Official product launch`,variant:`success`,icon:`🎉`}]},examples:{vertical:{variant:`vertical`,dateFormat:`long`,items:[{time:`2024-01-15`,title:`Project Started`,description:`Kickoff meeting and initial planning`,variant:`success`},{time:`2024-02-01`,title:`First Milestone`,description:`Completed initial design phase`,variant:`info`}]},horizontal:{variant:`horizontal`,dateFormat:`short`,items:[{time:`2024-01-01`,title:`Q1`,description:`First quarter`,variant:`default`},{time:`2024-04-01`,title:`Q2`,description:`Second quarter`,variant:`info`},{time:`2024-07-01`,title:`Q3`,description:`Third quarter`,variant:`warning`},{time:`2024-10-01`,title:`Q4`,description:`Fourth quarter`,variant:`success`}]},gantt:{variant:`gantt`,dateFormat:`short`,timeScale:`month`,rowLabel:`Projects`,items:[{label:`Backend Development`,items:[{title:`API Design`,startDate:`2024-01-01`,endDate:`2024-01-31`,variant:`success`},{title:`Implementation`,startDate:`2024-02-01`,endDate:`2024-03-31`,variant:`info`}]},{label:`Frontend Development`,items:[{title:`UI Design`,startDate:`2024-01-15`,endDate:`2024-02-15`,variant:`warning`},{title:`Component Dev`,startDate:`2024-02-15`,endDate:`2024-04-15`,variant:`default`}]},{label:`Testing`,items:[{title:`QA Phase`,startDate:`2024-03-01`,endDate:`2024-04-30`,variant:`danger`}]}]}}});var T=(0,c.createSafeTranslation)({"timeline.bucket.overdue":`Overdue`,"timeline.bucket.today":`Today`,"timeline.bucket.tomorrow":`Tomorrow`,"timeline.bucket.thisWeek":`This week`,"timeline.bucket.nextWeek":`Next week`,"timeline.bucket.later":`Later`,"timeline.bucket.noDate":`No date`,"timeline.bucket.unassigned":`Unassigned`,"timeline.relative.today":`Today`,"timeline.relative.tomorrow":`Tomorrow`,"timeline.relative.yesterday":`Yesterday`,"timeline.relative.inDays":`In {{n}} days`,"timeline.relative.daysAgo":`{{n}} days ago`},`timeline.bucket.today`),E={fieldOptionLabel:(e,t,n,r)=>r,translateOptions:(e,t,n)=>n,fieldLabel:(e,t,n)=>n};function D(){return(0,a.useObjectLabel)()??E}var O=s.z.object({title:s.z.string().optional(),date:s.z.string().optional(),description:s.z.string().optional(),variant:s.z.string().optional()}),k=s.z.object({mapping:O.optional(),objectName:s.z.string().optional(),titleField:s.z.string().optional(),dateField:s.z.string().optional(),startDateField:s.z.string().optional(),endDateField:s.z.string().optional(),descriptionField:s.z.string().optional(),groupByField:s.z.string().optional(),colorField:s.z.string().optional(),scale:s.z.enum([`hour`,`day`,`week`,`month`,`quarter`,`year`]).optional()}),A=({schema:e,dataSource:s,className:c,onRowClick:l,onItemClick:u,...d})=>{let[f,p]=(0,t.useState)([]),[m,h]=(0,t.useState)(()=>{let t=Array.isArray(e.items)&&e.items.length>0,n=Array.isArray(d.data)&&d.data.length>0;return!t&&!n&&!!e.objectName}),[g,_]=(0,t.useState)(null),[v,y]=(0,t.useState)(0),[b,x]=(0,t.useState)(null),S=e.timeline;(0,t.useEffect)(()=>{let t=k.safeParse(e);t.success||console.warn(`[ObjectTimeline] Invalid timeline configuration:`,t.error.format())},[e]);let C=(0,a.useDataScope)(e.bind);(0,t.useEffect)(()=>{let t=!0;return(async()=>{if(!(!s||typeof s.getObjectSchema!=`function`||!e.objectName))try{let n=await s.getObjectSchema(e.objectName);t&&x(n)}catch(e){console.warn(`Failed to fetch object def for ObjectTimeline`,e)}})(),()=>{t=!1}},[e.objectName,s]),(0,t.useEffect)(()=>{e.objectName&&!C&&!e.items&&!d.data?(async()=>{if(!s||typeof s.find!=`function`||!e.objectName){h(!1);return}h(!0);try{let t=(0,i.buildExpandFields)(b?.fields),n=await s.find(e.objectName,{options:{$top:100},...t.length>0?{$expand:t}:{}}),r=(0,i.extractRecords)(n);p(r)}catch(e){console.error(e),_(e)}finally{h(!1)}})():h(!1)},[e.objectName,s,C,e.items,d.data,v,b]);let E=d.data||C||f,{t:O}=T(),{fieldOptionLabel:A}=D(),j=S?.titleField??e.mapping?.title??e.titleField??`name`,M=S?.startDateField??S?.dateField??e.mapping?.date??e.startDateField??e.dateField??`date`,N=S?.endDateField??e.endDateField??M,P=e.mapping?.description??e.descriptionField??`description`,F=e.mapping?.variant??`variant`,I=S?.groupByField??e.groupByField,L=S?.colorField??e.colorField,R=(0,t.useMemo)(()=>{if(e.items)return e.items;if(!E||!Array.isArray(E))return[];let t=b?.fields??{},n=e.objectName||``,r=e=>{if(!e||!t[e]?.options)return{};let n={};for(let r of t[e].options)r&&r.value!=null&&(n[String(r.value)]=r);return n},i=r(L),a=Array.isArray(S?.metaFields)?S.metaFields.filter(e=>typeof e==`string`&&e):[`status`,`priority`].filter(e=>t[e]),o={};for(let e of a)o[e]=r(e);let s=e=>{if(e==null||e===``)return;let t=i[String(e)];if(t?.color)return String(t.color);let n=String(e);if(/^#([0-9a-f]{3}){1,2}$/i.test(n)||n.startsWith(`rgb`)||n.startsWith(`hsl`))return n},c=(e,t,r)=>{if(t==null||t===``)return null;let i=r[String(t)];return{label:i?.label?A(n,e,String(t),i.label):String(t),color:i?.color}},l=E.map(e=>{let t=e[M],r=e[N],i=L?e[L]:void 0,l=I?e[I]:void 0,u=[];if(n)for(let t of a){let n=c(t,e[t],o[t]||{});n&&u.push({key:t,label:n.label,color:n.color})}return{title:e[j],time:t,startDate:t,endDate:r,description:e[P],variant:e[F]||`default`,color:s(i),group:l,meta:u,_data:e}});l.sort((e,t)=>(e.startDate?new Date(e.startDate).getTime():1/0)-(t.startDate?new Date(t.startDate).getTime():1/0));let u=new Date,d=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),f=d(u),p=864e5,m=f-(u.getDay()+6)%7*p+7*p,h=m+7*p,g=e=>{if(!e)return O(`timeline.bucket.noDate`);let t=d(new Date(e));return Number.isNaN(t)?O(`timeline.bucket.noDate`):t<f?O(`timeline.bucket.overdue`):t===f?O(`timeline.bucket.today`):t===f+p?O(`timeline.bucket.tomorrow`):O(t<m?`timeline.bucket.thisWeek`:t<h?`timeline.bucket.nextWeek`:`timeline.bucket.later`)};if(I&&!l.every(e=>e.group==null||e.group===``)){let e=r(I);return l.map(t=>{let n=c(I,t.group,e);return{...t,group:n?n.label:t.group!=null&&t.group!==``?String(t.group):O(`timeline.bucket.unassigned`)}})}return l.map(e=>({...e,group:g(e.startDate)}))},[e.items,E,b,e.objectName,j,M,N,P,F,L,I,O,A]),z=(0,t.useCallback)(async()=>{y(e=>e+1)},[]),{ref:B,isRefreshing:V,pullDistance:H}=(0,o.usePullToRefresh)({onRefresh:z,enabled:!!e.objectName&&!!s}),U=(0,a.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l??u}),W=S?.scale??e.scale,G={...e,items:R||[],className:c||e.className,...W?{timeScale:W}:{},onItemClick:e=>{let t=e._data||e;U.handleClick(t),u?.(t)}};return g?(0,r.jsxs)(`div`,{className:`p-4 text-destructive`,"data-testid":`timeline-error`,role:`alert`,children:[`Error loading timeline: `,g.message]}):m&&(!R||R.length===0)?(0,r.jsxs)(`div`,{className:`flex flex-col h-full min-h-[200px] p-4 gap-3`,"data-testid":`timeline-loading`,role:`status`,"aria-live":`polite`,"aria-busy":`true`,children:[(0,r.jsx)(`span`,{className:`sr-only`,children:`Loading timeline…`}),[0,1,2,3].map(e=>(0,r.jsxs)(`div`,{className:`flex items-start gap-3`,style:{opacity:Math.max(.3,1-e*.18)},children:[(0,r.jsx)(`div`,{className:`h-3 w-3 rounded-full bg-muted/70 animate-pulse mt-1.5 shrink-0`}),(0,r.jsxs)(`div`,{className:`flex-1 space-y-2`,children:[(0,r.jsx)(`div`,{className:`h-4 w-1/3 rounded bg-muted/70 animate-pulse`}),(0,r.jsx)(`div`,{className:`h-3 w-2/3 rounded bg-muted/50 animate-pulse`})]})]},e))]}):(0,r.jsxs)(`div`,{ref:B,className:`relative overflow-auto h-full min-w-0`,children:[H>0&&(0,r.jsx)(`div`,{className:`flex items-center justify-center text-xs text-muted-foreground`,style:{height:H},children:V?`Refreshing…`:`Pull to refresh`}),(0,r.jsx)(w,{schema:G}),U.isOverlay&&(0,r.jsx)(n.NavigationOverlay,{...U,title:`Timeline Item`,children:e=>(0,r.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,r.jsxs)(`div`,{className:`flex flex-col`,children:[(0,r.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,r.jsx)(`span`,{className:`text-sm`,children:String(t??`—`)})]},e))})})]})},j=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`ol`,{ref:i,className:(0,n.cn)(`relative ml-3 border-l border-gray-200`,e),...t}));j.displayName=`Timeline`;var M=(0,n.cva)(`ml-6`,{variants:{density:{default:`mb-10`,compact:`mb-3`,comfortable:`mb-6`}},defaultVariants:{density:`default`}}),N=t.forwardRef(({className:e,density:t,...i},a)=>(0,r.jsx)(`li`,{ref:a,className:(0,n.cn)(M({density:t}),e),...i}));N.displayName=`TimelineItem`;var P=(0,n.cva)(`absolute -left-3 w-6 h-6 rounded-full border-2 flex items-center justify-center`,{variants:{variant:{default:`bg-blue-200 border-blue-400`,success:`bg-emerald-200 border-emerald-500`,warning:`bg-amber-200 border-amber-500`,danger:`bg-red-200 border-red-500`,info:`bg-purple-200 border-purple-500`,todo:`bg-slate-200 border-slate-400`,"in-progress":`bg-blue-200 border-blue-500`,done:`bg-emerald-200 border-emerald-500`}},defaultVariants:{variant:`default`}}),F=t.forwardRef(({className:e,variant:t=`default`,...i},a)=>(0,r.jsx)(`div`,{ref:a,className:(0,n.cn)(P({variant:t}),e),...i}));F.displayName=`TimelineMarker`;var I=t.forwardRef(({className:e,...t},n)=>(0,r.jsx)(`div`,{ref:n,className:e,...t}));I.displayName=`TimelineContent`;var L=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`h3`,{ref:i,className:(0,n.cn)(`font-semibold text-lg mb-1`,e),...t}));L.displayName=`TimelineTitle`;var R=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`time`,{ref:i,className:(0,n.cn)(`text-sm font-normal text-gray-500 mb-2 block`,e),...t}));R.displayName=`TimelineTime`;var z=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`p`,{ref:i,className:(0,n.cn)(`text-base text-gray-700`,e),...t}));z.displayName=`TimelineDescription`;var B=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`relative flex overflow-x-auto py-8`,e),...t}));B.displayName=`TimelineHorizontal`;var V=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`shrink-0 w-64 relative`,e),...t}));V.displayName=`TimelineHorizontalItem`;var H=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`relative w-full border rounded-lg overflow-hidden`,e),...t}));H.displayName=`TimelineGantt`;var U=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex border-b bg-gray-50`,e),...t}));U.displayName=`TimelineGanttHeader`;var W=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`w-48 border-r bg-white`,e),...t}));W.displayName=`TimelineGanttRowLabels`;var G=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex-1 overflow-x-auto`,e),...t}));G.displayName=`TimelineGanttGrid`;var K=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex items-center border-b min-h-12`,e),...t}));K.displayName=`TimelineGanttRow`;var q=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`px-4 py-2 font-medium text-sm truncate`,e),...t}));q.displayName=`TimelineGanttLabel`;var J=t.forwardRef(({className:e,start:t=0,width:i=100,variant:a=`default`,...o},s)=>(0,r.jsx)(`div`,{ref:s,className:(0,n.cn)(`absolute h-8 rounded-md transition-colors cursor-pointer`,{default:`bg-blue-500 hover:bg-blue-600`,success:`bg-green-500 hover:bg-green-600`,warning:`bg-yellow-500 hover:bg-yellow-600`,danger:`bg-red-500 hover:bg-red-600`,info:`bg-purple-500 hover:bg-purple-600`}[a],e),style:{left:`${t}%`,width:`${i}%`},...o}));J.displayName=`TimelineGanttBar`;var Y=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`px-2 py-1 text-white text-xs font-medium truncate`,e),...t}));Y.displayName=`TimelineGanttBarContent`;var X=({schema:e,...t})=>{let{dataSource:n}=(0,a.useSchemaContext)()||{};return(0,r.jsx)(A,{schema:e,dataSource:n,...t})};i.ComponentRegistry.register(`object-timeline`,X,{namespace:`plugin-timeline`,label:`Object Timeline`,category:`view`,inputs:[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],defaultValue:`vertical`}]}),i.ComponentRegistry.register(`timeline`,X,{namespace:`view`,label:`Timeline View`,category:`view`,inputs:[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],defaultValue:`vertical`}]}),e.ObjectTimeline=A,e.ObjectTimelineRenderer=X,e.TIMELINE_SCALES=g,e.Timeline=j,e.TimelineContent=I,e.TimelineDescription=z,e.TimelineGantt=H,e.TimelineGanttBar=J,e.TimelineGanttBarContent=Y,e.TimelineGanttGrid=G,e.TimelineGanttHeader=U,e.TimelineGanttLabel=q,e.TimelineGanttRow=K,e.TimelineGanttRowLabels=W,e.TimelineHorizontal=B,e.TimelineHorizontalItem=V,e.TimelineItem=N,e.TimelineMarker=F,e.TimelineRenderer=w,e.TimelineTime=R,e.TimelineTitle=L,e.generateTimeScaleHeaders=v,e.resolveTimelineScale=_,e.timelineItemVariants=M,e.timelineMarkerVariants=P});
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react"),require("@object-ui/components"),require("react/jsx-runtime"),require("@object-ui/core"),require("@object-ui/i18n"),require("@object-ui/react"),require("@object-ui/mobile"),require("zod")):typeof define==`function`&&define.amd?define([`exports`,`react`,`@object-ui/components`,`react/jsx-runtime`,`@object-ui/core`,`@object-ui/i18n`,`@object-ui/react`,`@object-ui/mobile`,`zod`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ObjectUIPluginTimeline={},e.React,e.ObjectUIComponents,e.react_jsx_runtime,e.ObjectUICore,e._object_ui_i18n,e.ObjectUIReact,e.ObjectUIMobile,e.zod))})(this,function(e,t,n,r,i,a,o,s,c){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var l=Object.create,u=Object.defineProperty,d=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyNames,p=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty,h=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=f(t),a=0,o=i.length,s;a<o;a++)s=i[a],!m.call(e,s)&&s!==n&&u(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=d(t,s))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:l(p(e)),h(t||!e||!e.__esModule||!m.call(e,`default`)?u(n,`default`,{value:e,enumerable:!0}):n,e)))(t,1);var g={"timeline.bucket.overdue":`Overdue`,"timeline.bucket.today":`Today`,"timeline.bucket.tomorrow":`Tomorrow`,"timeline.bucket.thisWeek":`This week`,"timeline.bucket.nextWeek":`Next week`,"timeline.bucket.later":`Later`,"timeline.bucket.noDate":`No date`,"timeline.bucket.unassigned":`Unassigned`,"timeline.relative.today":`Today`,"timeline.relative.tomorrow":`Tomorrow`,"timeline.relative.yesterday":`Yesterday`,"timeline.relative.inDays":`In {{n}} days`,"timeline.relative.daysAgo":`{{n}} days ago`,"timeline.scale.week":`Week {{n}}`,"timeline.scale.quarter":`Q{{quarter}} {{year}}`,"timeline.gantt.rowLabel":`Items`},_=`timeline.bucket.today`,v=(e,t)=>Object.entries(t??{}).reduce((e,[t,n])=>e.split(`{{${t}}}`).join(String(n)),g[e]||e),y=(0,a.createSafeTranslation)(g,_),b=new Set([`hour`,`day`,`week`,`month`,`quarter`,`year`]);function x(e){let t=e.scale??e.timeScale;return typeof t==`string`&&b.has(t)?t:`month`}function S(e,t,n,r=`en`,i=v){let a=[],o=new Date(t),s=new Date(n);if(Number.isNaN(o.getTime())||Number.isNaN(s.getTime())||o>s)return a;let c=new Date(o);switch(e){case`hour`:for(;c<=s;)a.push(c.toLocaleString(r,{month:`short`,day:`numeric`,hour:`numeric`})),c.setHours(c.getHours()+1);break;case`day`:for(;c<=s;)a.push(c.toLocaleDateString(r,{month:`short`,day:`numeric`})),c.setDate(c.getDate()+1);break;case`week`:{let e=1;for(;c<=s;)a.push(i(`timeline.scale.week`,{n:e++})),c.setDate(c.getDate()+7);break}case`quarter`:for(c.setMonth(Math.floor(c.getMonth()/3)*3,1);c<=s;)a.push(i(`timeline.scale.quarter`,{quarter:Math.floor(c.getMonth()/3)+1,year:c.getFullYear()})),c.setMonth(c.getMonth()+3);break;case`year`:for(c.setMonth(0,1);c<=s;)a.push(String(c.getFullYear())),c.setFullYear(c.getFullYear()+1);break;default:for(;c<=s;)a.push(c.toLocaleDateString(r,{month:`short`,year:`numeric`})),c.setMonth(c.getMonth()+1)}return a}function C(e){let t=e.flatMap(e=>(e.items||[]).flatMap(e=>[e.startDate,e.endDate])),n=Math.min(...t.map(e=>new Date(e).getTime())),r=Math.max(...t.map(e=>new Date(e).getTime()));return{minDate:new Date(n).toISOString().split(`T`)[0],maxDate:new Date(r).toISOString().split(`T`)[0]}}function w(e,t,n,r){let i=new Date(e).getTime(),a=new Date(t).getTime(),o=new Date(n).getTime(),s=new Date(r).getTime()-o,c=i-o,l=a-i;return{start:c/s*100,width:l/s*100}}function T(e,t,n){let r=new Date(e);return t===`short`?r.toLocaleDateString(n):t===`long`?r.toLocaleDateString(n,{year:`numeric`,month:`long`,day:`numeric`}):r.toISOString().split(`T`)[0]}function E({label:e,color:t}){let i=t?{backgroundColor:`${t}22`,color:t,borderColor:`${t}55`}:void 0;return(0,r.jsx)(`span`,{className:(0,n.cn)(`inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-medium`,!t&&`bg-muted text-muted-foreground border-transparent`),style:i,children:e})}function D(e){let t=[];for(let n of e){let e=n.group==null?``:String(n.group),r=t[t.length-1];r&&r.key===e?r.items.push(n):t.push({key:e,items:[n]})}return t}var O=({schema:e,className:t,...i})=>{let{variant:o=`vertical`,items:s=[],dateFormat:c=`short`,onItemClick:l}=e,u=(0,a.useDisplayLocale)(),{t:d}=y();if(o===`vertical`){let e=D(s),a=e.some(e=>e.key!==``),o=(e,t)=>{let i=e.color?{backgroundColor:`${e.color}33`,borderColor:e.color}:void 0,a=e.time?T(e.time,c,u):e.startDate?T(e.startDate,c,u):``,o=e.endDate&&e.endDate!==e.startDate?T(e.endDate,c,u):``,s=Array.isArray(e.meta)?e.meta:[];return(0,r.jsxs)(P,{density:`compact`,className:(0,n.cn)(e.className,l&&`cursor-pointer`),onClick:()=>l?.(e),children:[(0,r.jsx)(I,{variant:e.color?`default`:e.variant||`default`,style:i,children:e.icon&&(0,r.jsx)(`span`,{className:`text-xs`,children:e.icon})}),(0,r.jsxs)(L,{children:[(a||o)&&(0,r.jsxs)(z,{dateTime:e.time||e.startDate,className:`!mb-1 text-xs`,children:[a,o&&(0,r.jsxs)(`span`,{className:`text-muted-foreground/70`,children:[` → `,o]})]}),e.title&&(0,r.jsx)(R,{className:`text-sm sm:text-base mb-1`,children:e.title}),s.length>0&&(0,r.jsx)(`div`,{className:`flex flex-wrap gap-1.5 mt-1 mb-1`,children:s.map(e=>(0,r.jsx)(E,{label:e.label,color:e.color},e.key))}),e.description&&(0,r.jsx)(B,{className:`text-sm text-muted-foreground line-clamp-2 sm:line-clamp-none`,children:e.description}),e.content&&(0,n.renderChildren)(e.content)]})]},t)};return a?(0,r.jsx)(`div`,{className:(0,n.cn)(`px-4 sm:px-6 py-2`,t),...i,children:e.map((e,t)=>(0,r.jsxs)(`section`,{className:`mb-4`,children:[(0,r.jsxs)(`header`,{className:`sticky top-0 z-10 -mx-4 sm:-mx-6 px-4 sm:px-6 py-1.5 backdrop-blur bg-background/90 text-xs font-semibold uppercase tracking-wide text-muted-foreground border-b`,children:[(0,r.jsx)(`span`,{children:e.key}),(0,r.jsx)(`span`,{className:`ml-2 text-muted-foreground/60 font-normal normal-case`,children:e.items.length})]}),(0,r.jsx)(M,{className:`mt-3`,children:e.items.map((e,n)=>o(e,`${t}-${n}`))})]},`${e.key}-${t}`))}):(0,r.jsx)(M,{className:t,...i,children:s.map((e,t)=>o(e,t))})}if(o===`horizontal`)return(0,r.jsx)(V,{className:(0,n.cn)(`overflow-x-auto [-webkit-overflow-scrolling:touch]`,t),...i,children:s.map((e,t)=>(0,r.jsxs)(H,{className:(0,n.cn)(e.className,l&&`cursor-pointer`),onClick:()=>l?.(e),children:[(0,r.jsxs)(`div`,{className:`flex flex-col items-center`,children:[(0,r.jsx)(I,{variant:e.variant||`default`,children:e.icon&&(0,r.jsx)(`span`,{className:`text-xs`,children:e.icon})}),(0,r.jsxs)(`div`,{className:`mt-4 text-center`,children:[e.time&&(0,r.jsx)(z,{dateTime:e.time,children:T(e.time,c,u)}),e.title&&(0,r.jsx)(R,{children:e.title}),e.description&&(0,r.jsx)(B,{className:`text-center line-clamp-2 sm:line-clamp-none`,children:e.description}),e.content&&(0,n.renderChildren)(e.content)]})]}),t<s.length-1&&(0,r.jsx)(`div`,{className:`absolute left-full w-16 border-t-2 border-gray-200 top-3`})]},t))});if(o===`gantt`){let a=C(s),o=e.minDate||a.minDate,f=e.maxDate||a.maxDate,p=S(x(e),o,f,u,d);return(0,r.jsxs)(U,{className:(0,n.cn)(`overflow-x-auto [-webkit-overflow-scrolling:touch]`,t),...i,children:[(0,r.jsxs)(W,{children:[(0,r.jsx)(G,{className:`flex items-center px-2 sm:px-4 py-2 sm:py-3`,children:(0,r.jsx)(`span`,{className:`font-semibold text-xs sm:text-sm`,children:e.rowLabel||d(`timeline.gantt.rowLabel`)})}),(0,r.jsx)(K,{children:(0,r.jsx)(`div`,{className:`flex h-full`,children:p.map((e,t)=>(0,r.jsx)(`div`,{className:`flex-1 px-1 sm:px-2 py-2 sm:py-3 border-r text-xs font-medium text-center`,children:e},t))})})]}),(0,r.jsx)(`div`,{children:(0,r.jsxs)(`div`,{className:`flex`,children:[(0,r.jsx)(G,{children:s.map((e,t)=>(0,r.jsx)(q,{children:(0,r.jsx)(J,{title:e.label,className:`truncate`,children:e.label})},t))}),(0,r.jsx)(K,{className:`relative`,children:s.map((e,t)=>(0,r.jsx)(q,{className:`relative`,children:(e.items||[]).map((n,i)=>{let a=w(n.startDate,n.endDate,o,f);return(0,r.jsx)(Y,{start:a.start,width:a.width,variant:n.variant||`default`,onClick:()=>l?.(n,e,t,i),title:`${n.title||``}\n${T(n.startDate,c,u)} - ${T(n.endDate,c,u)}`,children:(0,r.jsx)(X,{children:n.title})},i)})},t))})]})})]})}return null};i.ComponentRegistry.register(`timeline`,O,{namespace:`plugin-timeline`,label:`Timeline`,category:`data-display`,inputs:[{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],label:`Timeline Variant`,defaultValue:`vertical`},{name:`items`,type:`array`,label:`Timeline Items`,description:`For vertical/horizontal: Array of { time, title, description, variant, icon, content }. For gantt: Array of { label, items: [{ title, startDate, endDate, variant }] }`},{name:`dateFormat`,type:`enum`,enum:[`short`,`long`,`iso`],label:`Date Format`,defaultValue:`short`},{name:`timeScale`,type:`enum`,enum:[`day`,`week`,`month`],label:`Time Scale (Gantt only)`,defaultValue:`month`},{name:`rowLabel`,type:`string`,label:`Row Label (Gantt only)`,defaultValue:`Items`},{name:`minDate`,type:`string`,label:`Min Date (Gantt only)`,description:`Override auto-calculated min date (YYYY-MM-DD)`},{name:`maxDate`,type:`string`,label:`Max Date (Gantt only)`,description:`Override auto-calculated max date (YYYY-MM-DD)`},{name:`className`,type:`string`,label:`CSS Class`}],defaultProps:{variant:`vertical`,dateFormat:`short`,items:[{time:`2024-01-15`,title:`Project Started`,description:`Kickoff meeting and initial planning`,variant:`success`,icon:`🚀`},{time:`2024-02-01`,title:`First Milestone`,description:`Completed initial design phase`,variant:`info`,icon:`🎨`},{time:`2024-03-15`,title:`Beta Release`,description:`Released beta version to testers`,variant:`warning`,icon:`⚡`},{time:`2024-04-01`,title:`Launch`,description:`Official product launch`,variant:`success`,icon:`🎉`}]},examples:{vertical:{variant:`vertical`,dateFormat:`long`,items:[{time:`2024-01-15`,title:`Project Started`,description:`Kickoff meeting and initial planning`,variant:`success`},{time:`2024-02-01`,title:`First Milestone`,description:`Completed initial design phase`,variant:`info`}]},horizontal:{variant:`horizontal`,dateFormat:`short`,items:[{time:`2024-01-01`,title:`Q1`,description:`First quarter`,variant:`default`},{time:`2024-04-01`,title:`Q2`,description:`Second quarter`,variant:`info`},{time:`2024-07-01`,title:`Q3`,description:`Third quarter`,variant:`warning`},{time:`2024-10-01`,title:`Q4`,description:`Fourth quarter`,variant:`success`}]},gantt:{variant:`gantt`,dateFormat:`short`,timeScale:`month`,rowLabel:`Projects`,items:[{label:`Backend Development`,items:[{title:`API Design`,startDate:`2024-01-01`,endDate:`2024-01-31`,variant:`success`},{title:`Implementation`,startDate:`2024-02-01`,endDate:`2024-03-31`,variant:`info`}]},{label:`Frontend Development`,items:[{title:`UI Design`,startDate:`2024-01-15`,endDate:`2024-02-15`,variant:`warning`},{title:`Component Dev`,startDate:`2024-02-15`,endDate:`2024-04-15`,variant:`default`}]},{label:`Testing`,items:[{title:`QA Phase`,startDate:`2024-03-01`,endDate:`2024-04-30`,variant:`danger`}]}]}}});var k=c.z.object({title:c.z.string().optional(),date:c.z.string().optional(),description:c.z.string().optional(),variant:c.z.string().optional()}),A=c.z.object({mapping:k.optional(),objectName:c.z.string().optional(),titleField:c.z.string().optional(),dateField:c.z.string().optional(),startDateField:c.z.string().optional(),endDateField:c.z.string().optional(),descriptionField:c.z.string().optional(),groupByField:c.z.string().optional(),colorField:c.z.string().optional(),scale:c.z.enum([`hour`,`day`,`week`,`month`,`quarter`,`year`]).optional()}),j=({schema:e,dataSource:a,className:c,onRowClick:l,onItemClick:u,...d})=>{let[f,p]=(0,t.useState)([]),[m,h]=(0,t.useState)(()=>{let t=Array.isArray(e.items)&&e.items.length>0,n=Array.isArray(d.data)&&d.data.length>0;return!t&&!n&&!!e.objectName}),[g,_]=(0,t.useState)(null),[v,b]=(0,t.useState)(0),[x,S]=(0,t.useState)(null),C=e.timeline;(0,t.useEffect)(()=>{let t=A.safeParse(e);t.success||console.warn(`[ObjectTimeline] Invalid timeline configuration:`,t.error.format())},[e]);let w=(0,o.useDataScope)(e.bind);(0,t.useEffect)(()=>{let t=!0;return(async()=>{if(!(!a||typeof a.getObjectSchema!=`function`||!e.objectName))try{let n=await a.getObjectSchema(e.objectName);t&&S(n)}catch(e){console.warn(`Failed to fetch object def for ObjectTimeline`,e)}})(),()=>{t=!1}},[e.objectName,a]);let T=JSON.stringify(e.filter??null),E=JSON.stringify(e.sort??null);(0,t.useEffect)(()=>{e.objectName&&!w&&!e.items&&!d.data?(async()=>{if(!a||typeof a.find!=`function`||!e.objectName){h(!1);return}h(!0);try{let t=(0,i.buildExpandFields)(x?.fields),n=await a.find(e.objectName,{$filter:e.filter,$orderby:(0,i.convertSortToQueryParams)(e.sort),$top:e.limit??100,...t.length>0?{$expand:t}:{}}),r=(0,i.extractRecords)(n);p(r)}catch(e){console.error(e),_(e)}finally{h(!1)}})():h(!1)},[e.objectName,a,w,e.items,d.data,v,x,T,E,e.limit]);let D=d.data||w||f,{t:k}=y(),{fieldOptionLabel:j}=(0,o.useSafeFieldLabel)(),M=C?.titleField??e.mapping?.title??e.titleField??`name`,N=C?.startDateField??C?.dateField??e.mapping?.date??e.startDateField??e.dateField??`date`,P=C?.endDateField??e.endDateField??N,F=e.mapping?.description??e.descriptionField??`description`,I=e.mapping?.variant??`variant`,L=C?.groupByField??e.groupByField,R=C?.colorField??e.colorField,z=(0,t.useMemo)(()=>{if(e.items)return e.items;if(!D||!Array.isArray(D))return[];let t=x?.fields??{},n=e.objectName||``,r=e=>{if(!e||!t[e]?.options)return{};let n={};for(let r of t[e].options)r&&r.value!=null&&(n[String(r.value)]=r);return n},i=r(R),a=Array.isArray(C?.metaFields)?C.metaFields.filter(e=>typeof e==`string`&&e):[`status`,`priority`].filter(e=>t[e]),o={};for(let e of a)o[e]=r(e);let s=e=>{if(e==null||e===``)return;let t=i[String(e)];if(t?.color)return String(t.color);let n=String(e);if(/^#([0-9a-f]{3}){1,2}$/i.test(n)||n.startsWith(`rgb`)||n.startsWith(`hsl`))return n},c=(e,t,r)=>{if(t==null||t===``)return null;let i=r[String(t)];return{label:i?.label?j(n,e,String(t),i.label):String(t),color:i?.color}},l=D.map(e=>{let t=e[N],r=e[P],i=R?e[R]:void 0,l=L?e[L]:void 0,u=[];if(n)for(let t of a){let n=c(t,e[t],o[t]||{});n&&u.push({key:t,label:n.label,color:n.color})}return{title:e[M],time:t,startDate:t,endDate:r,description:e[F],variant:e[I]||`default`,color:s(i),group:l,meta:u,_data:e}});l.sort((e,t)=>(e.startDate?new Date(e.startDate).getTime():1/0)-(t.startDate?new Date(t.startDate).getTime():1/0));let u=new Date,d=e=>new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime(),f=d(u),p=864e5,m=f-(u.getDay()+6)%7*p+7*p,h=m+7*p,g=e=>{if(!e)return k(`timeline.bucket.noDate`);let t=d(new Date(e));return Number.isNaN(t)?k(`timeline.bucket.noDate`):t<f?k(`timeline.bucket.overdue`):t===f?k(`timeline.bucket.today`):t===f+p?k(`timeline.bucket.tomorrow`):k(t<m?`timeline.bucket.thisWeek`:t<h?`timeline.bucket.nextWeek`:`timeline.bucket.later`)};if(L&&!l.every(e=>e.group==null||e.group===``)){let e=r(L);return l.map(t=>{let n=c(L,t.group,e);return{...t,group:n?n.label:t.group!=null&&t.group!==``?String(t.group):k(`timeline.bucket.unassigned`)}})}return l.map(e=>({...e,group:g(e.startDate)}))},[e.items,D,x,e.objectName,M,N,P,F,I,R,L,k,j]),B=(0,t.useCallback)(async()=>{b(e=>e+1)},[]),{ref:V,isRefreshing:H,pullDistance:U}=(0,s.usePullToRefresh)({onRefresh:B,enabled:!!e.objectName&&!!a}),W=(0,o.useNavigationOverlay)({navigation:e.navigation,objectName:e.objectName,onRowClick:l??u}),G=C?.scale??e.scale,K={...e,items:z||[],className:c||e.className,...G?{timeScale:G}:{},onItemClick:e=>{let t=e._data||e;W.handleClick(t),u?.(t)}};return g?(0,r.jsxs)(`div`,{className:`p-4 text-destructive`,"data-testid":`timeline-error`,role:`alert`,children:[`Error loading timeline: `,g.message]}):m&&(!z||z.length===0)?(0,r.jsxs)(`div`,{className:`flex flex-col h-full min-h-[200px] p-4 gap-3`,"data-testid":`timeline-loading`,role:`status`,"aria-live":`polite`,"aria-busy":`true`,children:[(0,r.jsx)(`span`,{className:`sr-only`,children:`Loading timeline…`}),[0,1,2,3].map(e=>(0,r.jsxs)(`div`,{className:`flex items-start gap-3`,style:{opacity:Math.max(.3,1-e*.18)},children:[(0,r.jsx)(`div`,{className:`h-3 w-3 rounded-full bg-muted/70 animate-pulse mt-1.5 shrink-0`}),(0,r.jsxs)(`div`,{className:`flex-1 space-y-2`,children:[(0,r.jsx)(`div`,{className:`h-4 w-1/3 rounded bg-muted/70 animate-pulse`}),(0,r.jsx)(`div`,{className:`h-3 w-2/3 rounded bg-muted/50 animate-pulse`})]})]},e))]}):(0,r.jsxs)(`div`,{ref:V,className:`relative overflow-auto h-full min-w-0`,children:[U>0&&(0,r.jsx)(`div`,{className:`flex items-center justify-center text-xs text-muted-foreground`,style:{height:U},children:H?`Refreshing…`:`Pull to refresh`}),(0,r.jsx)(O,{schema:K}),W.isOverlay&&(0,r.jsx)(n.NavigationOverlay,{...W,title:`Timeline Item`,children:e=>(0,r.jsx)(`div`,{className:`space-y-3`,children:Object.entries(e).map(([e,t])=>(0,r.jsxs)(`div`,{className:`flex flex-col`,children:[(0,r.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:e.replace(/_/g,` `)}),(0,r.jsx)(`span`,{className:`text-sm`,children:String(t??`—`)})]},e))})})]})},M=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`ol`,{ref:i,className:(0,n.cn)(`relative ml-3 border-l border-gray-200`,e),...t}));M.displayName=`Timeline`;var N=(0,n.cva)(`ml-6`,{variants:{density:{default:`mb-10`,compact:`mb-3`,comfortable:`mb-6`}},defaultVariants:{density:`default`}}),P=t.forwardRef(({className:e,density:t,...i},a)=>(0,r.jsx)(`li`,{ref:a,className:(0,n.cn)(N({density:t}),e),...i}));P.displayName=`TimelineItem`;var F=(0,n.cva)(`absolute -left-3 w-6 h-6 rounded-full border-2 flex items-center justify-center`,{variants:{variant:{default:`bg-blue-200 border-blue-400`,success:`bg-emerald-200 border-emerald-500`,warning:`bg-amber-200 border-amber-500`,danger:`bg-red-200 border-red-500`,info:`bg-purple-200 border-purple-500`,todo:`bg-slate-200 border-slate-400`,"in-progress":`bg-blue-200 border-blue-500`,done:`bg-emerald-200 border-emerald-500`}},defaultVariants:{variant:`default`}}),I=t.forwardRef(({className:e,variant:t=`default`,...i},a)=>(0,r.jsx)(`div`,{ref:a,className:(0,n.cn)(F({variant:t}),e),...i}));I.displayName=`TimelineMarker`;var L=t.forwardRef(({className:e,...t},n)=>(0,r.jsx)(`div`,{ref:n,className:e,...t}));L.displayName=`TimelineContent`;var R=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`h3`,{ref:i,className:(0,n.cn)(`font-semibold text-lg mb-1`,e),...t}));R.displayName=`TimelineTitle`;var z=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`time`,{ref:i,className:(0,n.cn)(`text-sm font-normal text-gray-500 mb-2 block`,e),...t}));z.displayName=`TimelineTime`;var B=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`p`,{ref:i,className:(0,n.cn)(`text-base text-gray-700`,e),...t}));B.displayName=`TimelineDescription`;var V=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`relative flex overflow-x-auto py-8`,e),...t}));V.displayName=`TimelineHorizontal`;var H=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`shrink-0 w-64 relative`,e),...t}));H.displayName=`TimelineHorizontalItem`;var U=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`relative w-full border rounded-lg overflow-hidden`,e),...t}));U.displayName=`TimelineGantt`;var W=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex border-b bg-gray-50`,e),...t}));W.displayName=`TimelineGanttHeader`;var G=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`w-48 border-r bg-white`,e),...t}));G.displayName=`TimelineGanttRowLabels`;var K=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex-1 overflow-x-auto`,e),...t}));K.displayName=`TimelineGanttGrid`;var q=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`flex items-center border-b min-h-12`,e),...t}));q.displayName=`TimelineGanttRow`;var J=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`px-4 py-2 font-medium text-sm truncate`,e),...t}));J.displayName=`TimelineGanttLabel`;var Y=t.forwardRef(({className:e,start:t=0,width:i=100,variant:a=`default`,...o},s)=>(0,r.jsx)(`div`,{ref:s,className:(0,n.cn)(`absolute h-8 rounded-md transition-colors cursor-pointer`,{default:`bg-blue-500 hover:bg-blue-600`,success:`bg-green-500 hover:bg-green-600`,warning:`bg-yellow-500 hover:bg-yellow-600`,danger:`bg-red-500 hover:bg-red-600`,info:`bg-purple-500 hover:bg-purple-600`}[a],e),style:{left:`${t}%`,width:`${i}%`},...o}));Y.displayName=`TimelineGanttBar`;var X=t.forwardRef(({className:e,...t},i)=>(0,r.jsx)(`div`,{ref:i,className:(0,n.cn)(`px-2 py-1 text-white text-xs font-medium truncate`,e),...t}));X.displayName=`TimelineGanttBarContent`;var Z={filter:!0,sort:!0,limit:`limit`},Q=({schema:e,...t})=>{let{dataSource:n}=(0,o.useSchemaContext)()||{};return(0,r.jsx)(o.ElementDataSourceGate,{schema:e,mapping:Z,dataSource:n,testId:`object-timeline`,errorTitle:`This timeline’s data source could not be resolved`,children:e=>(0,r.jsx)(j,{schema:e,dataSource:n,...t})})};i.ComponentRegistry.register(`object-timeline`,Q,{namespace:`plugin-timeline`,label:`Object Timeline`,category:`view`,inputs:[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],defaultValue:`vertical`}]}),i.ComponentRegistry.register(`timeline`,Q,{namespace:`view`,label:`Timeline View`,category:`view`,inputs:[{name:`objectName`,type:`string`,label:`Object Name`,required:!0},{name:`variant`,type:`enum`,enum:[`vertical`,`horizontal`,`gantt`],defaultValue:`vertical`}]}),e.ObjectTimeline=j,e.ObjectTimelineRenderer=Q,e.TIMELINE_SCALES=b,e.Timeline=M,e.TimelineContent=L,e.TimelineDescription=B,e.TimelineGantt=U,e.TimelineGanttBar=Y,e.TimelineGanttBarContent=X,e.TimelineGanttGrid=K,e.TimelineGanttHeader=W,e.TimelineGanttLabel=J,e.TimelineGanttRow=q,e.TimelineGanttRowLabels=G,e.TimelineHorizontal=V,e.TimelineHorizontalItem=H,e.TimelineItem=P,e.TimelineMarker=I,e.TimelineRenderer=O,e.TimelineTime=z,e.TimelineTitle=R,e.generateTimeScaleHeaders=S,e.resolveTimelineScale=x,e.timelineItemVariants=N,e.timelineMarkerVariants=F});
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { TimelineSchema } from '@object-ui/types';
|
|
2
|
+
import { TimelineTranslate } from './useTimelineTranslation';
|
|
2
3
|
/**
|
|
3
4
|
* ObjectUI
|
|
4
5
|
* Copyright (c) 2024-present ObjectStack Inc.
|
|
@@ -30,8 +31,25 @@ export declare function resolveTimelineScale(schema: {
|
|
|
30
31
|
* scale produces a non-empty header row — `hour` / `quarter` / `year` used to
|
|
31
32
|
* fall through the month/week/day chain and return `[]`, blanking the axis
|
|
32
33
|
* (#2942). Exported for the spec-parity test.
|
|
34
|
+
*
|
|
35
|
+
* `locale` is threaded in rather than read here: this is a pure function, and
|
|
36
|
+
* the session's locale lives behind a hook (#4513). The three `Intl` branches
|
|
37
|
+
* below used to pass a literal `'en-US'`, so a fully Chinese timeline rendered
|
|
38
|
+
* an English axis. The default is `'en'` — the same concrete last resort
|
|
39
|
+
* `useDisplayLocale()` falls back to, and byte-identical to the retired
|
|
40
|
+
* `'en-US'` at all three sites — so the existing 3-argument call sites keep
|
|
41
|
+
* producing exactly what they produced before.
|
|
42
|
+
*
|
|
43
|
+
* `t` is threaded on the same seam and for the same reason (#4520). The two are
|
|
44
|
+
* different kinds of dependency and each covers what the other cannot: a locale
|
|
45
|
+
* TAG formats a date, a TRANSLATION spells a word. The `week` and `quarter`
|
|
46
|
+
* branches never touched `Intl`, so #4513 left them reading `Week 1` / `Q3
|
|
47
|
+
* 2026` on an axis that had just become Chinese. Its default is the package's
|
|
48
|
+
* own defaults table, which is what the channel serves with no `I18nProvider`
|
|
49
|
+
* mounted, so 3- and 4-argument call sites keep producing byte-identical
|
|
50
|
+
* English.
|
|
33
51
|
*/
|
|
34
|
-
export declare function generateTimeScaleHeaders(scale: string, minDate: string, maxDate: string): string[];
|
|
52
|
+
export declare function generateTimeScaleHeaders(scale: string, minDate: string, maxDate: string, locale?: string, t?: TimelineTranslate): string[];
|
|
35
53
|
export declare const TimelineRenderer: ({ schema, className, ...props }: {
|
|
36
54
|
schema: TimelineSchema;
|
|
37
55
|
className?: string;
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAsBvD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAGlC;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,WAAW,CAAC,MAAM,CAE9C,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,MAAM,CAG7F;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAa,EACrB,CAAC,GAAE,iBAA4C,GAC9C,MAAM,EAAE,CAyDV;AAsGD,eAAO,MAAM,gBAAgB,GAAI,iCAAiC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,6BAsPjI,CAAC"}
|
|
@@ -12,6 +12,31 @@
|
|
|
12
12
|
* embed) without an I18nProvider on the React tree.
|
|
13
13
|
*/
|
|
14
14
|
export declare const TIMELINE_DEFAULT_TRANSLATIONS: Record<string, string>;
|
|
15
|
+
/**
|
|
16
|
+
* The translate fn shape this package threads into its pure helpers.
|
|
17
|
+
*
|
|
18
|
+
* `generateTimeScaleHeaders` is a module-level function and cannot host a hook,
|
|
19
|
+
* so the component reads the channel and passes `t` down — the same seam
|
|
20
|
+
* objectui#4513 opened for the resolved `locale` string, for the same reason.
|
|
21
|
+
*/
|
|
22
|
+
export type TimelineTranslate = (key: string, params?: Record<string, unknown>) => string;
|
|
23
|
+
/**
|
|
24
|
+
* The English last resort for call sites that have no `t` to hand: the exported
|
|
25
|
+
* helper's default parameter, and nothing else.
|
|
26
|
+
*
|
|
27
|
+
* It is the same lookup `createSafeTranslation` serves on a provider-less host,
|
|
28
|
+
* spelled here because that one is a hook and this is a pure function. Both
|
|
29
|
+
* halves are deliberate mirrors of `useSafeTranslation.ts` and must stay that
|
|
30
|
+
* way — a divergence would only ever show up on hosts with no `I18nProvider`,
|
|
31
|
+
* where we are least likely to see it:
|
|
32
|
+
*
|
|
33
|
+
* - `||` (not `??`) for the chain, so an empty string falls through to the
|
|
34
|
+
* key exactly as the hook's `defaults[key] || …` chain does.
|
|
35
|
+
* - `split().join()` (not `replace`/`replaceAll`) for interpolation, which is
|
|
36
|
+
* literal on both sides and substitutes EVERY occurrence — i18next's own
|
|
37
|
+
* behaviour, and the objectui#3418 fix.
|
|
38
|
+
*/
|
|
39
|
+
export declare const translateTimelineDefault: TimelineTranslate;
|
|
15
40
|
/**
|
|
16
41
|
* Was a local re-implementation that wrapped the hook in try/catch — a
|
|
17
42
|
* rules-of-hooks violation (objectui#2879, same class as #2595/#2596).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTimelineTranslation.d.ts","sourceRoot":"","sources":["../src/useTimelineTranslation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"useTimelineTranslation.d.ts","sourceRoot":"","sources":["../src/useTimelineTranslation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuBhE,CAAC;AAIF;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAIpC,CAAC;AAEJ;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;4BA1ElC,CAAC;;;;;CA6ED,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-timeline",
|
|
3
|
-
"version": "17.
|
|
3
|
+
"version": "17.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Timeline component plugin for Object UI",
|
|
@@ -24,15 +24,15 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@objectstack/spec": "^17.0.0
|
|
27
|
+
"@objectstack/spec": "^17.0.0",
|
|
28
28
|
"class-variance-authority": "^0.7.1",
|
|
29
29
|
"zod": "^4.4.3",
|
|
30
|
-
"@object-ui/components": "17.
|
|
31
|
-
"@object-ui/core": "17.
|
|
32
|
-
"@object-ui/i18n": "17.
|
|
33
|
-
"@object-ui/mobile": "17.
|
|
34
|
-
"@object-ui/react": "17.
|
|
35
|
-
"@object-ui/types": "17.
|
|
30
|
+
"@object-ui/components": "17.6.0",
|
|
31
|
+
"@object-ui/core": "17.6.0",
|
|
32
|
+
"@object-ui/i18n": "17.6.0",
|
|
33
|
+
"@object-ui/mobile": "17.6.0",
|
|
34
|
+
"@object-ui/react": "17.6.0",
|
|
35
|
+
"@object-ui/types": "17.6.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -43,9 +43,9 @@
|
|
|
43
43
|
"@types/react-dom": "19.2.4",
|
|
44
44
|
"@vitejs/plugin-react": "^6.0.5",
|
|
45
45
|
"typescript": "^6.0.3",
|
|
46
|
-
"vite": "^8.2.
|
|
46
|
+
"vite": "^8.2.1",
|
|
47
47
|
"vite-plugin-dts": "^5.0.3",
|
|
48
|
-
"@object-ui/data-objectstack": "17.
|
|
48
|
+
"@object-ui/data-objectstack": "17.6.0"
|
|
49
49
|
},
|
|
50
50
|
"keywords": [
|
|
51
51
|
"objectui",
|