timeline-scheduler 0.1.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/README.md +370 -0
- package/dist/components/tl-grid.d.ts +12 -0
- package/dist/components/tl-item.d.ts +73 -0
- package/dist/timeline-scheduler.cjs.js +637 -0
- package/dist/timeline-scheduler.d.ts +103 -0
- package/dist/timeline-scheduler.es.js +1801 -0
- package/dist/types.d.ts +63 -0
- package/dist/utils/layout.d.ts +7 -0
- package/dist/utils/layout.test.d.ts +1 -0
- package/dist/utils/time.d.ts +16 -0
- package/dist/utils/time.test.d.ts +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=globalThis,t=e.ShadowRoot&&(e.ShadyCSS===void 0||e.ShadyCSS.nativeShadow)&&`adoptedStyleSheets`in Document.prototype&&`replace`in CSSStyleSheet.prototype,n=Symbol(),r=new WeakMap,i=class{constructor(e,t,r){if(this._$cssResult$=!0,r!==n)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o,n=this.t;if(t&&e===void 0){let t=n!==void 0&&n.length===1;t&&(e=r.get(n)),e===void 0&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&r.set(n,e))}return e}toString(){return this.cssText}},a=e=>new i(typeof e==`string`?e:e+``,void 0,n),o=(e,...t)=>new i(e.length===1?e[0]:t.reduce((t,n,r)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if(typeof e==`number`)return e;throw Error(`Value passed to 'css' function must be a 'css' function result: `+e+`. Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.`)})(n)+e[r+1],e[0]),e,n),s=(n,r)=>{if(t)n.adoptedStyleSheets=r.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(let t of r){let r=document.createElement(`style`),i=e.litNonce;i!==void 0&&r.setAttribute(`nonce`,i),r.textContent=t.cssText,n.appendChild(r)}},c=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t=``;for(let n of e.cssRules)t+=n.cssText;return a(t)})(e):e,{is:l,defineProperty:u,getOwnPropertyDescriptor:d,getOwnPropertyNames:ee,getOwnPropertySymbols:te,getPrototypeOf:ne}=Object,f=globalThis,re=f.trustedTypes,ie=re?re.emptyScript:``,ae=f.reactiveElementPolyfillSupport,p=(e,t)=>e,m={toAttribute(e,t){switch(t){case Boolean:e=e?ie:null;break;case Object:case Array:e=e==null?e:JSON.stringify(e)}return e},fromAttribute(e,t){let n=e;switch(t){case Boolean:n=e!==null;break;case Number:n=e===null?null:Number(e);break;case Object:case Array:try{n=JSON.parse(e)}catch{n=null}}return n}},h=(e,t)=>!l(e,t),oe={attribute:!0,type:String,converter:m,reflect:!1,useDefault:!1,hasChanged:h};Symbol.metadata??=Symbol(`metadata`),f.litPropertyMetadata??=new WeakMap;var g=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=oe){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){let n=Symbol(),r=this.getPropertyDescriptor(e,n,t);r!==void 0&&u(this.prototype,e,r)}}static getPropertyDescriptor(e,t,n){let{get:r,set:i}=d(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:r,set(t){let a=r?.call(this);i?.call(this,t),this.requestUpdate(e,a,n)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??oe}static _$Ei(){if(this.hasOwnProperty(p(`elementProperties`)))return;let e=ne(this);e.finalize(),e.l!==void 0&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(p(`finalized`)))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(p(`properties`))){let e=this.properties,t=[...ee(e),...te(e)];for(let n of t)this.createProperty(n,e[n])}let e=this[Symbol.metadata];if(e!==null){let t=litPropertyMetadata.get(e);if(t!==void 0)for(let[e,n]of t)this.elementProperties.set(e,n)}this._$Eh=new Map;for(let[e,t]of this.elementProperties){let n=this._$Eu(e,t);n!==void 0&&this._$Eh.set(n,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){let t=[];if(Array.isArray(e)){let n=new Set(e.flat(1/0).reverse());for(let e of n)t.unshift(c(e))}else e!==void 0&&t.push(c(e));return t}static _$Eu(e,t){let n=t.attribute;return!1===n?void 0:typeof n==`string`?n:typeof e==`string`?e.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),this.renderRoot!==void 0&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){let e=new Map,t=this.constructor.elementProperties;for(let n of t.keys())this.hasOwnProperty(n)&&(e.set(n,this[n]),delete this[n]);e.size>0&&(this._$Ep=e)}createRenderRoot(){let e=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return s(e,this.constructor.elementStyles),e}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,n){this._$AK(e,n)}_$ET(e,t){let n=this.constructor.elementProperties.get(e),r=this.constructor._$Eu(e,n);if(r!==void 0&&!0===n.reflect){let i=(n.converter?.toAttribute===void 0?m:n.converter).toAttribute(t,n.type);this._$Em=e,i==null?this.removeAttribute(r):this.setAttribute(r,i),this._$Em=null}}_$AK(e,t){let n=this.constructor,r=n._$Eh.get(e);if(r!==void 0&&this._$Em!==r){let e=n.getPropertyOptions(r),i=typeof e.converter==`function`?{fromAttribute:e.converter}:e.converter?.fromAttribute===void 0?m:e.converter;this._$Em=r;let a=i.fromAttribute(t,e.type);this[r]=a??this._$Ej?.get(r)??a,this._$Em=null}}requestUpdate(e,t,n,r=!1,i){if(e!==void 0){let a=this.constructor;if(!1===r&&(i=this[e]),n??=a.getPropertyOptions(e),!((n.hasChanged??h)(i,t)||n.useDefault&&n.reflect&&i===this._$Ej?.get(e)&&!this.hasAttribute(a._$Eu(e,n))))return;this.C(e,t,n)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:n,reflect:r,wrapped:i},a){n&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,a??t??this[e]),!0!==i||a!==void 0)||(this._$AL.has(e)||(this.hasUpdated||n||(t=void 0),this._$AL.set(e,t)),!0===r&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}let e=this.scheduleUpdate();return e!=null&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(let[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}let e=this.constructor.elementProperties;if(e.size>0)for(let[t,n]of e){let{wrapped:e}=n,r=this[t];!0!==e||this._$AL.has(t)||r===void 0||this.C(t,void 0,n,r)}}let e=!1,t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};g.elementStyles=[],g.shadowRootOptions={mode:`open`},g[p(`elementProperties`)]=new Map,g[p(`finalized`)]=new Map,ae?.({ReactiveElement:g}),(f.reactiveElementVersions??=[]).push(`2.1.2`);var _=globalThis,se=e=>e,v=_.trustedTypes,ce=v?v.createPolicy(`lit-html`,{createHTML:e=>e}):void 0,le=`$lit$`,y=`lit$${Math.random().toFixed(9).slice(2)}$`,ue=`?`+y,de=`<${ue}>`,b=document,x=()=>b.createComment(``),S=e=>e===null||typeof e!=`object`&&typeof e!=`function`,C=Array.isArray,fe=e=>C(e)||typeof e?.[Symbol.iterator]==`function`,w=`[
|
|
2
|
+
\f\r]`,T=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,pe=/-->/g,me=/>/g,E=RegExp(`>|${w}(?:([^\\s"'>=/]+)(${w}*=${w}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,`g`),D=/'/g,O=/"/g,k=/^(?:script|style|textarea|title)$/i,A=(e=>(t,...n)=>({_$litType$:e,strings:t,values:n}))(1),j=Symbol.for(`lit-noChange`),M=Symbol.for(`lit-nothing`),N=new WeakMap,P=b.createTreeWalker(b,129);function F(e,t){if(!C(e)||!e.hasOwnProperty(`raw`))throw Error(`invalid template strings array`);return ce===void 0?t:ce.createHTML(t)}var he=(e,t)=>{let n=e.length-1,r=[],i,a=t===2?`<svg>`:t===3?`<math>`:``,o=T;for(let t=0;t<n;t++){let n=e[t],s,c,l=-1,u=0;for(;u<n.length&&(o.lastIndex=u,c=o.exec(n),c!==null);)u=o.lastIndex,o===T?c[1]===`!--`?o=pe:c[1]===void 0?c[2]===void 0?c[3]!==void 0&&(o=E):(k.test(c[2])&&(i=RegExp(`</`+c[2],`g`)),o=E):o=me:o===E?c[0]===`>`?(o=i??T,l=-1):c[1]===void 0?l=-2:(l=o.lastIndex-c[2].length,s=c[1],o=c[3]===void 0?E:c[3]===`"`?O:D):o===O||o===D?o=E:o===pe||o===me?o=T:(o=E,i=void 0);let d=o===E&&e[t+1].startsWith(`/>`)?` `:``;a+=o===T?n+de:l>=0?(r.push(s),n.slice(0,l)+le+n.slice(l)+y+d):n+y+(l===-2?t:d)}return[F(e,a+(e[n]||`<?>`)+(t===2?`</svg>`:t===3?`</math>`:``)),r]},I=class e{constructor({strings:t,_$litType$:n},r){let i;this.parts=[];let a=0,o=0,s=t.length-1,c=this.parts,[l,u]=he(t,n);if(this.el=e.createElement(l,r),P.currentNode=this.el.content,n===2||n===3){let e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;(i=P.nextNode())!==null&&c.length<s;){if(i.nodeType===1){if(i.hasAttributes())for(let e of i.getAttributeNames())if(e.endsWith(le)){let t=u[o++],n=i.getAttribute(e).split(y),r=/([.?@])?(.*)/.exec(t);c.push({type:1,index:a,name:r[2],strings:n,ctor:r[1]===`.`?_e:r[1]===`?`?ve:r[1]===`@`?ye:z}),i.removeAttribute(e)}else e.startsWith(y)&&(c.push({type:6,index:a}),i.removeAttribute(e));if(k.test(i.tagName)){let e=i.textContent.split(y),t=e.length-1;if(t>0){i.textContent=v?v.emptyScript:``;for(let n=0;n<t;n++)i.append(e[n],x()),P.nextNode(),c.push({type:2,index:++a});i.append(e[t],x())}}}else if(i.nodeType===8)if(i.data===ue)c.push({type:2,index:a});else{let e=-1;for(;(e=i.data.indexOf(y,e+1))!==-1;)c.push({type:7,index:a}),e+=y.length-1}a++}}static createElement(e,t){let n=b.createElement(`template`);return n.innerHTML=e,n}};function L(e,t,n=e,r){if(t===j)return t;let i=r===void 0?n._$Cl:n._$Co?.[r],a=S(t)?void 0:t._$litDirective$;return i?.constructor!==a&&(i?._$AO?.(!1),a===void 0?i=void 0:(i=new a(e),i._$AT(e,n,r)),r===void 0?n._$Cl=i:(n._$Co??=[])[r]=i),i!==void 0&&(t=L(e,i._$AS(e,t.values),i,r)),t}var ge=class{constructor(e,t){this._$AV=[],this._$AN=void 0,this._$AD=e,this._$AM=t}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(e){let{el:{content:t},parts:n}=this._$AD,r=(e?.creationScope??b).importNode(t,!0);P.currentNode=r;let i=P.nextNode(),a=0,o=0,s=n[0];for(;s!==void 0;){if(a===s.index){let t;s.type===2?t=new R(i,i.nextSibling,this,e):s.type===1?t=new s.ctor(i,s.name,s.strings,this,e):s.type===6&&(t=new be(i,this,e)),this._$AV.push(t),s=n[++o]}a!==s?.index&&(i=P.nextNode(),a++)}return P.currentNode=b,r}p(e){let t=0;for(let n of this._$AV)n!==void 0&&(n.strings===void 0?n._$AI(e[t]):(n._$AI(e,n,t),t+=n.strings.length-2)),t++}},R=class e{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(e,t,n,r){this.type=2,this._$AH=M,this._$AN=void 0,this._$AA=e,this._$AB=t,this._$AM=n,this.options=r,this._$Cv=r?.isConnected??!0}get parentNode(){let e=this._$AA.parentNode,t=this._$AM;return t!==void 0&&e?.nodeType===11&&(e=t.parentNode),e}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(e,t=this){e=L(this,e,t),S(e)?e===M||e==null||e===``?(this._$AH!==M&&this._$AR(),this._$AH=M):e!==this._$AH&&e!==j&&this._(e):e._$litType$===void 0?e.nodeType===void 0?fe(e)?this.k(e):this._(e):this.T(e):this.$(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==M&&S(this._$AH)?this._$AA.nextSibling.data=e:this.T(b.createTextNode(e)),this._$AH=e}$(e){let{values:t,_$litType$:n}=e,r=typeof n==`number`?this._$AC(e):(n.el===void 0&&(n.el=I.createElement(F(n.h,n.h[0]),this.options)),n);if(this._$AH?._$AD===r)this._$AH.p(t);else{let e=new ge(r,this),n=e.u(this.options);e.p(t),this.T(n),this._$AH=e}}_$AC(e){let t=N.get(e.strings);return t===void 0&&N.set(e.strings,t=new I(e)),t}k(t){C(this._$AH)||(this._$AH=[],this._$AR());let n=this._$AH,r,i=0;for(let a of t)i===n.length?n.push(r=new e(this.O(x()),this.O(x()),this,this.options)):r=n[i],r._$AI(a),i++;i<n.length&&(this._$AR(r&&r._$AB.nextSibling,i),n.length=i)}_$AR(e=this._$AA.nextSibling,t){for(this._$AP?.(!1,!0,t);e!==this._$AB;){let t=se(e).nextSibling;se(e).remove(),e=t}}setConnected(e){this._$AM===void 0&&(this._$Cv=e,this._$AP?.(e))}},z=class{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(e,t,n,r,i){this.type=1,this._$AH=M,this._$AN=void 0,this.element=e,this.name=t,this._$AM=r,this.options=i,n.length>2||n[0]!==``||n[1]!==``?(this._$AH=Array(n.length-1).fill(new String),this.strings=n):this._$AH=M}_$AI(e,t=this,n,r){let i=this.strings,a=!1;if(i===void 0)e=L(this,e,t,0),a=!S(e)||e!==this._$AH&&e!==j,a&&(this._$AH=e);else{let r=e,o,s;for(e=i[0],o=0;o<i.length-1;o++)s=L(this,r[n+o],t,o),s===j&&(s=this._$AH[o]),a||=!S(s)||s!==this._$AH[o],s===M?e=M:e!==M&&(e+=(s??``)+i[o+1]),this._$AH[o]=s}a&&!r&&this.j(e)}j(e){e===M?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,e??``)}},_e=class extends z{constructor(){super(...arguments),this.type=3}j(e){this.element[this.name]=e===M?void 0:e}},ve=class extends z{constructor(){super(...arguments),this.type=4}j(e){this.element.toggleAttribute(this.name,!!e&&e!==M)}},ye=class extends z{constructor(e,t,n,r,i){super(e,t,n,r,i),this.type=5}_$AI(e,t=this){if((e=L(this,e,t,0)??M)===j)return;let n=this._$AH,r=e===M&&n!==M||e.capture!==n.capture||e.once!==n.once||e.passive!==n.passive,i=e!==M&&(n===M||r);r&&this.element.removeEventListener(this.name,this,n),i&&this.element.addEventListener(this.name,this,e),this._$AH=e}handleEvent(e){typeof this._$AH==`function`?this._$AH.call(this.options?.host??this.element,e):this._$AH.handleEvent(e)}},be=class{constructor(e,t,n){this.element=e,this.type=6,this._$AN=void 0,this._$AM=t,this.options=n}get _$AU(){return this._$AM._$AU}_$AI(e){L(this,e)}},xe=_.litHtmlPolyfillSupport;xe?.(I,R),(_.litHtmlVersions??=[]).push(`3.3.2`);var Se=(e,t,n)=>{let r=n?.renderBefore??t,i=r._$litPart$;if(i===void 0){let e=n?.renderBefore??null;r._$litPart$=i=new R(t.insertBefore(x(),e),e,void 0,n??{})}return i._$AI(e),i},B=globalThis,V=class extends g{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){let e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){let t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=Se(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return j}};V._$litElement$=!0,V.finalized=!0,B.litElementHydrateSupport?.({LitElement:V});var Ce=B.litElementPolyfillSupport;Ce?.({LitElement:V}),(B.litElementVersions??=[]).push(`4.2.2`);var H=e=>(t,n)=>{n===void 0?customElements.define(e,t):n.addInitializer(()=>{customElements.define(e,t)})},we={attribute:!0,type:String,converter:m,reflect:!1,hasChanged:h},Te=(e=we,t,n)=>{let{kind:r,metadata:i}=n,a=globalThis.litPropertyMetadata.get(i);if(a===void 0&&globalThis.litPropertyMetadata.set(i,a=new Map),r===`setter`&&((e=Object.create(e)).wrapped=!0),a.set(n.name,e),r===`accessor`){let{name:r}=n;return{set(n){let i=t.get.call(this);t.set.call(this,n),this.requestUpdate(r,i,e,!0,n)},init(t){return t!==void 0&&this.C(r,void 0,e,t),t}}}if(r===`setter`){let{name:r}=n;return function(n){let i=this[r];t.call(this,n),this.requestUpdate(r,i,e,!0,n)}}throw Error(`Unsupported decorator location: `+r)};function U(e){return(t,n)=>typeof n==`object`?Te(e,t,n):((e,t,n)=>{let r=t.hasOwnProperty(n);return t.constructor.createProperty(n,e),r?Object.getOwnPropertyDescriptor(t,n):void 0})(e,t,n)}function W(e){return U({...e,state:!0,attribute:!1})}function G(e,t,n){return Math.min(Math.max(e,t),n)}function K(e,t,n){let r=(n-t)*60;return G(((e.getHours()-t)*60+e.getMinutes())/r*100,0,100)}function q(e,t,n,r){let i=(n-t)*60,a=G(e,0,100)/100*i,o=new Date(r);return o.setHours(t,0,0,0),o.setMinutes(o.getMinutes()+Math.round(a)),o}function J(e,t){if(t<=0)return new Date(e);let n=new Date(e),r=n.getHours()*60+n.getMinutes(),i=Math.round(r/t)*t;return n.setHours(Math.floor(i/60),i%60,0,0),n}function Ee(e){let t=new Map;if(e.length===0)return t;let n=[...e].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=[];for(let e of n){let n=!1;for(let i=0;i<r.length;i++)if(r[i]<=e.start.getTime()){t.set(e.id,i),r[i]=e.end.getTime(),n=!0;break}n||(t.set(e.id,r.length),r.push(e.end.getTime()))}return t}function Y(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}var X=class extends V{constructor(...e){super(...e),this.startHour=0,this.endHour=24}static{this.styles=o`
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
flex: 1;
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
.header {
|
|
9
|
+
position: relative;
|
|
10
|
+
height: 28px;
|
|
11
|
+
background: var(--tl-header-bg, #f8fafc);
|
|
12
|
+
border-bottom: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
13
|
+
/* Same gradient as resource-content so lines are pixel-identical */
|
|
14
|
+
background-image: repeating-linear-gradient(
|
|
15
|
+
to right,
|
|
16
|
+
transparent,
|
|
17
|
+
transparent calc((100% / var(--_hour-count)) - 1px),
|
|
18
|
+
var(--tl-grid-line-color, #e2e8f0) calc((100% / var(--_hour-count)) - 1px),
|
|
19
|
+
var(--tl-grid-line-color, #e2e8f0) calc(100% / var(--_hour-count))
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
.hour-label {
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: 0;
|
|
25
|
+
height: 100%;
|
|
26
|
+
padding-left: 4px;
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
font-size: 11px;
|
|
30
|
+
color: var(--tl-time-label-color, #94a3b8);
|
|
31
|
+
font-family: var(--tl-font-family, inherit);
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
pointer-events: none;
|
|
34
|
+
}
|
|
35
|
+
`}render(){let e=this.endHour-this.startHour,t=[];for(let e=this.startHour;e<this.endHour;e++)t.push(e);return A`
|
|
36
|
+
<div class="header" style="--_hour-count: ${e}">
|
|
37
|
+
${t.map(t=>A`
|
|
38
|
+
<div class="hour-label" style="left: ${(t-this.startHour)/e*100}%">
|
|
39
|
+
${String(t).padStart(2,`0`)}:00
|
|
40
|
+
</div>
|
|
41
|
+
`)}
|
|
42
|
+
</div>
|
|
43
|
+
`}};Y([U({type:Number})],X.prototype,`startHour`,void 0),Y([U({type:Number})],X.prototype,`endHour`,void 0),X=Y([H(`tl-grid`)],X);var Z=class extends V{constructor(...e){super(...e),this.dragEnabled=!0,this.resizable=!1,this.showTime=!0,this.showTooltip=!0,this.readonly=!1,this.renderContent=null,this._tooltipVisible=!1,this._tooltipRect=null,this._downX=0,this._downY=0,this._downPointerId=-1,this._holdTimer=0,this._lastClickTime=0,this._onHoldMove=e=>{if(e.pointerId!==this._downPointerId)return;let t=Math.abs(e.clientX-this._downX),n=Math.abs(e.clientY-this._downY);this.dragEnabled&&(t>5||n>5)&&(clearTimeout(this._holdTimer),this._cleanHoldListeners(),this._startDrag(e.pointerId,e.clientX,e.clientY))},this._onHoldUp=e=>{clearTimeout(this._holdTimer),this._cleanHoldListeners();let t=Math.abs(e.clientX-this._downX),n=Math.abs(e.clientY-this._downY);if(t<5&&n<5){let e=Date.now(),t=e-this._lastClickTime<350;this._lastClickTime=t?0:e,this.dispatchEvent(new CustomEvent(t?`tl-item-dblclick`:`tl-item-click`,{bubbles:!0,composed:!0,detail:{item:this.item}}))}},this._onHoldCancel=()=>{clearTimeout(this._holdTimer),this._cleanHoldListeners()}}static{this.styles=o`
|
|
44
|
+
:host {
|
|
45
|
+
display: block;
|
|
46
|
+
position: absolute;
|
|
47
|
+
overflow: visible;
|
|
48
|
+
}
|
|
49
|
+
.block {
|
|
50
|
+
position: absolute;
|
|
51
|
+
inset: 4px 2px;
|
|
52
|
+
border-radius: var(--tl-item-radius, 4px);
|
|
53
|
+
color: var(--tl-item-text-color, #ffffff);
|
|
54
|
+
font-family: var(--tl-font-family, inherit);
|
|
55
|
+
font-size: 12px;
|
|
56
|
+
font-weight: 500;
|
|
57
|
+
padding: 0 8px;
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
cursor: grab;
|
|
63
|
+
user-select: none;
|
|
64
|
+
box-sizing: border-box;
|
|
65
|
+
transition: opacity 0.1s;
|
|
66
|
+
outline-offset: 2px;
|
|
67
|
+
}
|
|
68
|
+
.block:focus-visible {
|
|
69
|
+
outline: 2px solid var(--tl-focus-color, #3b82f6);
|
|
70
|
+
}
|
|
71
|
+
.block.no-drag {
|
|
72
|
+
cursor: default;
|
|
73
|
+
}
|
|
74
|
+
:host(.dragging) .block {
|
|
75
|
+
opacity: var(--tl-item-opacity-dragging, 0.4);
|
|
76
|
+
cursor: grabbing;
|
|
77
|
+
}
|
|
78
|
+
.name {
|
|
79
|
+
white-space: nowrap;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
text-overflow: ellipsis;
|
|
82
|
+
}
|
|
83
|
+
.time {
|
|
84
|
+
font-size: 10px;
|
|
85
|
+
font-weight: 400;
|
|
86
|
+
opacity: 0.85;
|
|
87
|
+
white-space: nowrap;
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
text-overflow: ellipsis;
|
|
90
|
+
}
|
|
91
|
+
.handle {
|
|
92
|
+
position: absolute;
|
|
93
|
+
top: 4px;
|
|
94
|
+
bottom: 4px;
|
|
95
|
+
width: 8px;
|
|
96
|
+
cursor: ew-resize;
|
|
97
|
+
z-index: 1;
|
|
98
|
+
}
|
|
99
|
+
.handle-left {
|
|
100
|
+
left: 2px;
|
|
101
|
+
border-radius: var(--tl-item-radius, 4px) 0 0 var(--tl-item-radius, 4px);
|
|
102
|
+
}
|
|
103
|
+
.handle-right {
|
|
104
|
+
right: 2px;
|
|
105
|
+
border-radius: 0 var(--tl-item-radius, 4px) var(--tl-item-radius, 4px) 0;
|
|
106
|
+
}
|
|
107
|
+
.tooltip {
|
|
108
|
+
position: fixed;
|
|
109
|
+
background: var(--tl-tooltip-bg, #1e293b);
|
|
110
|
+
color: var(--tl-tooltip-color, #ffffff);
|
|
111
|
+
font-size: 12px;
|
|
112
|
+
line-height: 1.5;
|
|
113
|
+
padding: 8px 10px;
|
|
114
|
+
border-radius: 6px;
|
|
115
|
+
white-space: nowrap;
|
|
116
|
+
pointer-events: none;
|
|
117
|
+
z-index: 9999;
|
|
118
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
|
119
|
+
transform: translateX(-50%) translateY(-100%);
|
|
120
|
+
}
|
|
121
|
+
.tooltip::after {
|
|
122
|
+
content: '';
|
|
123
|
+
position: absolute;
|
|
124
|
+
top: 100%;
|
|
125
|
+
left: 50%;
|
|
126
|
+
transform: translateX(-50%);
|
|
127
|
+
border: 5px solid transparent;
|
|
128
|
+
border-top-color: var(--tl-tooltip-bg, #1e293b);
|
|
129
|
+
}
|
|
130
|
+
.tooltip-title {
|
|
131
|
+
font-weight: 600;
|
|
132
|
+
margin-bottom: 2px;
|
|
133
|
+
}
|
|
134
|
+
.tooltip-description {
|
|
135
|
+
opacity: 0.8;
|
|
136
|
+
font-size: 11px;
|
|
137
|
+
margin-bottom: 4px;
|
|
138
|
+
}
|
|
139
|
+
.tooltip-time {
|
|
140
|
+
opacity: 0.7;
|
|
141
|
+
font-size: 11px;
|
|
142
|
+
}
|
|
143
|
+
`}render(){let e=this.item.start.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}),t=this.item.end.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`});return A`
|
|
144
|
+
<div
|
|
145
|
+
class="block ${this.readonly||!this.dragEnabled?`no-drag`:``}"
|
|
146
|
+
role="button"
|
|
147
|
+
tabindex="0"
|
|
148
|
+
aria-label="${this.item.name}, ${e} – ${t}"
|
|
149
|
+
style="background-color: ${this.item.color}"
|
|
150
|
+
@pointerdown=${this.readonly?M:this._onPointerDown}
|
|
151
|
+
@pointerenter=${this.readonly?M:this._onPointerEnter}
|
|
152
|
+
@pointerleave=${this.readonly?M:this._onPointerLeave}
|
|
153
|
+
@contextmenu=${this.readonly?M:this._onContextMenu}
|
|
154
|
+
@keydown=${this.readonly?M:this._onKeyDown}
|
|
155
|
+
>
|
|
156
|
+
${this.renderContent?this.renderContent(this.item):A`
|
|
157
|
+
<span class="name">${this.item.name}</span>
|
|
158
|
+
${this.showTime?A`<span class="time">${e} – ${t}</span>`:M}
|
|
159
|
+
`}
|
|
160
|
+
${!this.readonly&&this.resizable?A`
|
|
161
|
+
<div class="handle handle-left" @pointerdown=${this._onResizeStart.bind(this,`left`)}></div>
|
|
162
|
+
<div class="handle handle-right" @pointerdown=${this._onResizeStart.bind(this,`right`)}></div>
|
|
163
|
+
`:M}
|
|
164
|
+
</div>
|
|
165
|
+
${this.showTooltip&&this._tooltipVisible&&this._tooltipRect?A`
|
|
166
|
+
<div class="tooltip" style="top: ${this._tooltipRect.top-8}px; left: ${this._tooltipRect.left+this._tooltipRect.width/2}px">
|
|
167
|
+
<div class="tooltip-title">${this.item.name}</div>
|
|
168
|
+
${this.item.description?A`<div class="tooltip-description">${this.item.description}</div>`:M}
|
|
169
|
+
<div class="tooltip-time">${e} – ${t} · ${this._formatDuration()}</div>
|
|
170
|
+
</div>
|
|
171
|
+
`:M}
|
|
172
|
+
`}_formatDuration(){let e=this.item.end.getTime()-this.item.start.getTime(),t=Math.round(e/6e4),n=Math.floor(t/60),r=t%60;return n===0?`${r}m`:r===0?`${n}h`:`${n}h ${r}m`}_onPointerDown(e){e.button===0&&(e.preventDefault(),this._downX=e.clientX,this._downY=e.clientY,this._downPointerId=e.pointerId,this.setPointerCapture(e.pointerId),this.addEventListener(`pointermove`,this._onHoldMove),this.addEventListener(`pointerup`,this._onHoldUp,{once:!0}),this.addEventListener(`pointercancel`,this._onHoldCancel,{once:!0}),this.dragEnabled&&(this._holdTimer=window.setTimeout(()=>this._startDrag(this._downPointerId,this._downX,this._downY),200)))}_cleanHoldListeners(){this.removeEventListener(`pointermove`,this._onHoldMove),this.removeEventListener(`pointerup`,this._onHoldUp),this.removeEventListener(`pointercancel`,this._onHoldCancel)}_startDrag(e,t,n){let r=this.shadowRoot.querySelector(`.block`).getBoundingClientRect();this.releasePointerCapture(e),this.dispatchEvent(new CustomEvent(`tl-item-dragstart`,{bubbles:!0,composed:!0,detail:{item:this.item,pointerId:e,clientX:t,clientY:n,itemClientLeft:r.left,itemClientWidth:r.width}}))}_onPointerEnter(e){e.pointerType!==`touch`&&(this._tooltipRect=this.shadowRoot.querySelector(`.block`).getBoundingClientRect(),this._tooltipVisible=!0,this.dispatchEvent(new CustomEvent(`tl-item-hover`,{bubbles:!0,composed:!0,detail:{item:this.item,type:`enter`}})))}_onPointerLeave(e){e.pointerType!==`touch`&&(this._tooltipVisible=!1,this._tooltipRect=null,this.dispatchEvent(new CustomEvent(`tl-item-hover`,{bubbles:!0,composed:!0,detail:{item:this.item,type:`leave`}})))}_onContextMenu(e){e.preventDefault(),this.dispatchEvent(new CustomEvent(`tl-item-contextmenu`,{bubbles:!0,composed:!0,detail:{item:this.item,x:e.clientX,y:e.clientY}}))}_onKeyDown(e){e.key!==`ArrowLeft`&&e.key!==`ArrowRight`||(e.preventDefault(),this.dispatchEvent(new CustomEvent(`tl-item-keymove`,{bubbles:!0,composed:!0,detail:{item:this.item,direction:e.key===`ArrowLeft`?`left`:`right`}})))}_onResizeStart(e,t){t.preventDefault(),t.stopPropagation();let n=this.shadowRoot.querySelector(`.block`).getBoundingClientRect();this.dispatchEvent(new CustomEvent(`tl-item-resize-start`,{bubbles:!0,composed:!0,detail:{item:this.item,edge:e,pointerId:t.pointerId,clientX:t.clientX,itemClientLeft:n.left,itemClientWidth:n.width}}))}};Y([U({attribute:!1})],Z.prototype,`item`,void 0),Y([U({type:Boolean})],Z.prototype,`dragEnabled`,void 0),Y([U({type:Boolean})],Z.prototype,`resizable`,void 0),Y([U({type:Boolean})],Z.prototype,`showTime`,void 0),Y([U({type:Boolean})],Z.prototype,`showTooltip`,void 0),Y([U({type:Boolean})],Z.prototype,`readonly`,void 0),Y([U({attribute:!1})],Z.prototype,`renderContent`,void 0),Y([W()],Z.prototype,`_tooltipVisible`,void 0),Y([W()],Z.prototype,`_tooltipRect`,void 0),Z=Y([H(`tl-item`)],Z);var Q=56,De=[`#6366f1`,`#8b5cf6`,`#ec4899`,`#f59e0b`,`#10b981`,`#0ea5e9`,`#f97316`],Oe=400,$=class extends V{constructor(...e){super(...e),this.resources=[],this.items=[],this.startHour=0,this.endHour=24,this.snapMinutes=15,this.date=(()=>{let e=new Date;return e.setHours(0,0,0,0),e})(),this.draggable=!0,this.resizable=!1,this.readonly=!1,this.showTime=!0,this.minDurationMinutes=0,this.maxDurationMinutes=0,this.zoom=1,this.showNav=!1,this.creatable=!1,this.renderItem=null,this.showAvatar=!0,this.showEventCount=!0,this.showTooltip=!0,this.showNowLine=!0,this.showZoomControls=!0,this.showDateNav=!0,this.editable=!0,this._dragState=null,this._createState=null,this._ctxState=null,this._now=new Date,this._editDraft=null,this._createPending=null,this._createHoldTimer=0,this._nowInterval=0}connectedCallback(){super.connectedCallback(),this._nowInterval=window.setInterval(()=>{this._now=new Date},6e4)}disconnectedCallback(){super.disconnectedCallback(),clearInterval(this._nowInterval),clearTimeout(this._createHoldTimer)}static{this.styles=o`
|
|
173
|
+
:host {
|
|
174
|
+
display: flex;
|
|
175
|
+
flex-direction: column;
|
|
176
|
+
font-family: var(--tl-font-family, sans-serif);
|
|
177
|
+
background: var(--tl-bg, #ffffff);
|
|
178
|
+
border: 1px solid var(--tl-resource-border-color, #e2e8f0);
|
|
179
|
+
border-radius: 4px;
|
|
180
|
+
overflow: hidden;
|
|
181
|
+
}
|
|
182
|
+
/* ── Navigation bar ─────────────────────────────────────────────────────── */
|
|
183
|
+
.nav-bar {
|
|
184
|
+
display: flex;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: 8px;
|
|
187
|
+
padding: 6px 12px;
|
|
188
|
+
background: var(--tl-header-bg, #f8fafc);
|
|
189
|
+
border-bottom: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
190
|
+
flex-shrink: 0;
|
|
191
|
+
position: relative;
|
|
192
|
+
}
|
|
193
|
+
.nav-group {
|
|
194
|
+
display: flex;
|
|
195
|
+
border: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
196
|
+
border-radius: 6px;
|
|
197
|
+
overflow: hidden;
|
|
198
|
+
background: var(--tl-bg, #ffffff);
|
|
199
|
+
}
|
|
200
|
+
.nav-btn {
|
|
201
|
+
width: 30px;
|
|
202
|
+
height: 30px;
|
|
203
|
+
font-size: 18px;
|
|
204
|
+
line-height: 1;
|
|
205
|
+
border: none;
|
|
206
|
+
border-right: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
207
|
+
background: transparent;
|
|
208
|
+
color: var(--tl-text-color, #1e293b);
|
|
209
|
+
cursor: pointer;
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
justify-content: center;
|
|
213
|
+
padding: 0;
|
|
214
|
+
font-family: var(--tl-font-family, inherit);
|
|
215
|
+
flex-shrink: 0;
|
|
216
|
+
}
|
|
217
|
+
.nav-btn:last-child {
|
|
218
|
+
border-right: none;
|
|
219
|
+
border-left: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
220
|
+
}
|
|
221
|
+
.nav-btn:hover { background: var(--tl-grid-line-color, #e2e8f0); }
|
|
222
|
+
.nav-date {
|
|
223
|
+
height: 30px;
|
|
224
|
+
padding: 0 14px;
|
|
225
|
+
font-size: 13px;
|
|
226
|
+
font-weight: 600;
|
|
227
|
+
color: var(--tl-text-color, #1e293b);
|
|
228
|
+
border: none;
|
|
229
|
+
background: transparent;
|
|
230
|
+
cursor: pointer;
|
|
231
|
+
font-family: var(--tl-font-family, inherit);
|
|
232
|
+
white-space: nowrap;
|
|
233
|
+
display: flex;
|
|
234
|
+
align-items: center;
|
|
235
|
+
}
|
|
236
|
+
.nav-date:hover { background: var(--tl-grid-line-color, #e2e8f0); }
|
|
237
|
+
.nav-date-input {
|
|
238
|
+
position: absolute;
|
|
239
|
+
opacity: 0;
|
|
240
|
+
pointer-events: none;
|
|
241
|
+
width: 0;
|
|
242
|
+
height: 0;
|
|
243
|
+
top: 100%;
|
|
244
|
+
left: 0;
|
|
245
|
+
border: none;
|
|
246
|
+
padding: 0;
|
|
247
|
+
}
|
|
248
|
+
.zoom-controls { display: flex; gap: 2px; flex-shrink: 0; margin-left: auto; }
|
|
249
|
+
.zoom-btn {
|
|
250
|
+
padding: 4px 10px;
|
|
251
|
+
font-size: 12px;
|
|
252
|
+
border: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
253
|
+
border-radius: 4px;
|
|
254
|
+
background: var(--tl-bg, #ffffff);
|
|
255
|
+
color: var(--tl-text-color, #1e293b);
|
|
256
|
+
cursor: pointer;
|
|
257
|
+
font-family: var(--tl-font-family, inherit);
|
|
258
|
+
}
|
|
259
|
+
.zoom-btn:hover { background: var(--tl-grid-line-color, #e2e8f0); }
|
|
260
|
+
.zoom-btn.active { background: #3b82f6; color: #ffffff; border-color: #3b82f6; }
|
|
261
|
+
/* ── Scroll wrapper ─────────────────────────────────────────────────────── */
|
|
262
|
+
.wrapper {
|
|
263
|
+
overflow: auto;
|
|
264
|
+
min-height: 0;
|
|
265
|
+
}
|
|
266
|
+
.zoom-content {
|
|
267
|
+
min-width: calc(var(--_zoom, 1) * 100%);
|
|
268
|
+
display: flex;
|
|
269
|
+
flex-direction: column;
|
|
270
|
+
}
|
|
271
|
+
/* ── Time header ────────────────────────────────────────────────────────── */
|
|
272
|
+
.header-row {
|
|
273
|
+
display: flex;
|
|
274
|
+
flex-shrink: 0;
|
|
275
|
+
position: sticky;
|
|
276
|
+
top: 0;
|
|
277
|
+
z-index: 3;
|
|
278
|
+
}
|
|
279
|
+
.corner {
|
|
280
|
+
flex-shrink: 0;
|
|
281
|
+
width: var(--tl-resource-col-width, 160px);
|
|
282
|
+
box-sizing: border-box;
|
|
283
|
+
background: var(--tl-header-bg, #f8fafc);
|
|
284
|
+
border-right: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
285
|
+
border-bottom: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
286
|
+
position: sticky;
|
|
287
|
+
left: 0;
|
|
288
|
+
z-index: 1;
|
|
289
|
+
}
|
|
290
|
+
/* ── Resource rows ──────────────────────────────────────────────────────── */
|
|
291
|
+
.resource-row {
|
|
292
|
+
display: flex;
|
|
293
|
+
border-bottom: 1px solid var(--tl-resource-border-color, #e2e8f0);
|
|
294
|
+
}
|
|
295
|
+
.resource-row:last-child { border-bottom: none; }
|
|
296
|
+
.resource-label {
|
|
297
|
+
flex-shrink: 0;
|
|
298
|
+
width: var(--tl-resource-col-width, 160px);
|
|
299
|
+
padding: 8px 12px;
|
|
300
|
+
color: var(--tl-text-color, #1e293b);
|
|
301
|
+
border-right: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
302
|
+
display: flex;
|
|
303
|
+
align-items: center;
|
|
304
|
+
gap: 8px;
|
|
305
|
+
box-sizing: border-box;
|
|
306
|
+
background: var(--tl-bg, #ffffff);
|
|
307
|
+
position: sticky;
|
|
308
|
+
left: 0;
|
|
309
|
+
z-index: 2;
|
|
310
|
+
}
|
|
311
|
+
.avatar {
|
|
312
|
+
width: 32px;
|
|
313
|
+
height: 32px;
|
|
314
|
+
border-radius: 50%;
|
|
315
|
+
object-fit: cover;
|
|
316
|
+
flex-shrink: 0;
|
|
317
|
+
}
|
|
318
|
+
.avatar-initials {
|
|
319
|
+
width: 32px;
|
|
320
|
+
height: 32px;
|
|
321
|
+
border-radius: 50%;
|
|
322
|
+
display: flex;
|
|
323
|
+
align-items: center;
|
|
324
|
+
justify-content: center;
|
|
325
|
+
font-size: 11px;
|
|
326
|
+
font-weight: 600;
|
|
327
|
+
color: #ffffff;
|
|
328
|
+
flex-shrink: 0;
|
|
329
|
+
}
|
|
330
|
+
.resource-info { flex: 1; min-width: 0; }
|
|
331
|
+
.resource-name {
|
|
332
|
+
font-size: 13px;
|
|
333
|
+
font-weight: 500;
|
|
334
|
+
white-space: nowrap;
|
|
335
|
+
overflow: hidden;
|
|
336
|
+
text-overflow: ellipsis;
|
|
337
|
+
}
|
|
338
|
+
.resource-count { font-size: 11px; color: #94a3b8; margin-top: 1px; }
|
|
339
|
+
/* ── Content area ───────────────────────────────────────────────────────── */
|
|
340
|
+
.resource-content {
|
|
341
|
+
position: relative;
|
|
342
|
+
flex: 1;
|
|
343
|
+
overflow: visible;
|
|
344
|
+
background-image: repeating-linear-gradient(
|
|
345
|
+
to right,
|
|
346
|
+
transparent,
|
|
347
|
+
transparent calc((100% / var(--_hour-count)) - 1px),
|
|
348
|
+
var(--tl-grid-line-color, #e2e8f0) calc((100% / var(--_hour-count)) - 1px),
|
|
349
|
+
var(--tl-grid-line-color, #e2e8f0) calc(100% / var(--_hour-count))
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
.resource-content.creatable { cursor: crosshair; }
|
|
353
|
+
.ghost {
|
|
354
|
+
position: absolute;
|
|
355
|
+
border-radius: var(--tl-item-radius, 4px);
|
|
356
|
+
opacity: 0.35;
|
|
357
|
+
pointer-events: none;
|
|
358
|
+
border: 2px dashed rgba(0, 0, 0, 0.3);
|
|
359
|
+
box-sizing: border-box;
|
|
360
|
+
}
|
|
361
|
+
.create-ghost {
|
|
362
|
+
position: absolute;
|
|
363
|
+
border-radius: var(--tl-item-radius, 4px);
|
|
364
|
+
opacity: 0.5;
|
|
365
|
+
pointer-events: none;
|
|
366
|
+
background: var(--tl-create-ghost-color, #3b82f6);
|
|
367
|
+
border: 2px dashed rgba(59, 130, 246, 0.8);
|
|
368
|
+
box-sizing: border-box;
|
|
369
|
+
}
|
|
370
|
+
.now-line {
|
|
371
|
+
position: absolute;
|
|
372
|
+
top: 0;
|
|
373
|
+
bottom: 0;
|
|
374
|
+
width: 2px;
|
|
375
|
+
background: var(--tl-now-line-color, #ef4444);
|
|
376
|
+
pointer-events: none;
|
|
377
|
+
z-index: 10;
|
|
378
|
+
transform: translateX(-50%);
|
|
379
|
+
}
|
|
380
|
+
/* ── Built-in context menu ──────────────────────────────────────────────── */
|
|
381
|
+
.ctx-backdrop {
|
|
382
|
+
position: fixed;
|
|
383
|
+
inset: 0;
|
|
384
|
+
z-index: 9998;
|
|
385
|
+
background: transparent;
|
|
386
|
+
}
|
|
387
|
+
.ctx-menu {
|
|
388
|
+
position: fixed;
|
|
389
|
+
background: var(--tl-bg, #ffffff);
|
|
390
|
+
border: 1px solid var(--tl-grid-line-color, #e2e8f0);
|
|
391
|
+
border-radius: 6px;
|
|
392
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
|
393
|
+
padding: 4px 0;
|
|
394
|
+
z-index: 9999;
|
|
395
|
+
min-width: 130px;
|
|
396
|
+
}
|
|
397
|
+
.ctx-item {
|
|
398
|
+
display: block;
|
|
399
|
+
width: 100%;
|
|
400
|
+
padding: 8px 14px;
|
|
401
|
+
border: none;
|
|
402
|
+
background: none;
|
|
403
|
+
text-align: left;
|
|
404
|
+
font-size: 13px;
|
|
405
|
+
cursor: pointer;
|
|
406
|
+
color: var(--tl-text-color, #1e293b);
|
|
407
|
+
font-family: var(--tl-font-family, inherit);
|
|
408
|
+
box-sizing: border-box;
|
|
409
|
+
}
|
|
410
|
+
.ctx-item:hover { background: #f1f5f9; }
|
|
411
|
+
.ctx-item.danger { color: #ef4444; }
|
|
412
|
+
.ctx-separator {
|
|
413
|
+
height: 1px;
|
|
414
|
+
background: var(--tl-grid-line-color, #e2e8f0);
|
|
415
|
+
margin: 4px 0;
|
|
416
|
+
}
|
|
417
|
+
/* ── Edit modal ─────────────────────────────────────────────────────────── */
|
|
418
|
+
.modal-backdrop {
|
|
419
|
+
position: fixed;
|
|
420
|
+
inset: 0;
|
|
421
|
+
background: rgba(0, 0, 0, 0.4);
|
|
422
|
+
z-index: 9999;
|
|
423
|
+
display: flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
justify-content: center;
|
|
426
|
+
}
|
|
427
|
+
.modal {
|
|
428
|
+
background: #ffffff;
|
|
429
|
+
border-radius: 10px;
|
|
430
|
+
padding: 24px;
|
|
431
|
+
width: 420px;
|
|
432
|
+
max-width: 90vw;
|
|
433
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
|
|
434
|
+
display: flex;
|
|
435
|
+
flex-direction: column;
|
|
436
|
+
gap: 20px;
|
|
437
|
+
}
|
|
438
|
+
.modal-title { font-size: 16px; font-weight: 600; color: var(--tl-text-color, #1e293b); margin: 0; }
|
|
439
|
+
.modal-fields { display: flex; flex-direction: column; gap: 14px; }
|
|
440
|
+
.modal-field { display: flex; flex-direction: column; gap: 4px; }
|
|
441
|
+
.modal-label { font-size: 12px; font-weight: 500; color: #64748b; }
|
|
442
|
+
.modal-row { display: flex; gap: 8px; }
|
|
443
|
+
.modal-input {
|
|
444
|
+
width: 100%;
|
|
445
|
+
padding: 7px 10px;
|
|
446
|
+
font-size: 13px;
|
|
447
|
+
border: 1px solid #e2e8f0;
|
|
448
|
+
border-radius: 6px;
|
|
449
|
+
box-sizing: border-box;
|
|
450
|
+
color: var(--tl-text-color, #1e293b);
|
|
451
|
+
background: #ffffff;
|
|
452
|
+
font-family: var(--tl-font-family, inherit);
|
|
453
|
+
}
|
|
454
|
+
.modal-input:focus { outline: none; border-color: #3b82f6; box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2); }
|
|
455
|
+
.modal-error { font-size: 12px; color: #ef4444; min-height: 16px; }
|
|
456
|
+
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; }
|
|
457
|
+
.modal-btn {
|
|
458
|
+
padding: 8px 18px;
|
|
459
|
+
font-size: 13px;
|
|
460
|
+
font-weight: 500;
|
|
461
|
+
border-radius: 6px;
|
|
462
|
+
border: 1px solid #e2e8f0;
|
|
463
|
+
cursor: pointer;
|
|
464
|
+
font-family: var(--tl-font-family, inherit);
|
|
465
|
+
background: #ffffff;
|
|
466
|
+
color: var(--tl-text-color, #1e293b);
|
|
467
|
+
}
|
|
468
|
+
.modal-btn:hover { background: #f8fafc; }
|
|
469
|
+
.modal-btn-primary { background: #3b82f6; color: #ffffff; border-color: #3b82f6; }
|
|
470
|
+
.modal-btn-primary:hover { background: #2563eb; border-color: #2563eb; }
|
|
471
|
+
`}get _validItems(){let e=new Set(this.resources.map(e=>e.id));return this.items.filter(t=>!t.id||!t.resourceId||!t.start||!t.end?(console.error(`[timeline-scheduler] Item missing required fields:`,t),!1):t.start>=t.end?(console.warn(`[timeline-scheduler] Item "${t.id}" has start >= end, skipping.`),!1):e.has(t.resourceId)?!!this._overlapsDate(t):(console.warn(`[timeline-scheduler] Item "${t.id}" has unknown resourceId "${t.resourceId}", skipping.`),!1))}_overlapsDate(e){let t=new Date(this.date);t.setHours(this.startHour,0,0,0);let n=new Date(this.date);return n.setHours(this.endHour,0,0,0),e.start<n&&e.end>t}_clipToDay(e){let t=new Date(this.date);t.setHours(this.startHour,0,0,0);let n=new Date(this.date);return n.setHours(this.endHour,0,0,0),{start:e.start<t?t:e.start,end:e.end>n?n:e.end}}_subRowMap(e){return Ee(this._validItems.filter(t=>t.resourceId===e))}_rowHeight(e){let t=this._subRowMap(e);return(t.size===0?1:Math.max(...Array.from(t.values()))+1)*Q}get _isToday(){let e=new Date;return this.date.getFullYear()===e.getFullYear()&&this.date.getMonth()===e.getMonth()&&this.date.getDate()===e.getDate()}_resourceColor(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return De[t%De.length]}_initials(e){return e.split(/\s+/).map(e=>e[0]??``).join(``).slice(0,2).toUpperCase()}render(){let e=this.endHour-this.startHour,t=K(this._now,this.startHour,this.endHour),n=this.showNowLine&&this._isToday&&t>=0&&t<=100,r=this._dragState,i=this._createState;return A`
|
|
472
|
+
${this.showNav&&(this.showDateNav||this.showZoomControls)?this._renderNav():M}
|
|
473
|
+
<div
|
|
474
|
+
class="wrapper"
|
|
475
|
+
@tl-item-dragstart=${this._onItemDragStart}
|
|
476
|
+
@tl-item-resize-start=${this._onItemResizeStart}
|
|
477
|
+
@tl-item-click=${this._onItemClick}
|
|
478
|
+
@tl-item-dblclick=${this._onItemDblClick}
|
|
479
|
+
@tl-item-hover=${this._onItemHover}
|
|
480
|
+
@tl-item-contextmenu=${this._onItemContextMenu}
|
|
481
|
+
@tl-item-keymove=${this._onItemKeyMove}
|
|
482
|
+
@pointermove=${this._onPointerMove}
|
|
483
|
+
@pointerup=${this._onPointerUp}
|
|
484
|
+
>
|
|
485
|
+
<div class="zoom-content" style="--_zoom: ${this.zoom}; --_hour-count: ${e}">
|
|
486
|
+
<div class="header-row">
|
|
487
|
+
<div class="corner"></div>
|
|
488
|
+
<tl-grid .startHour=${this.startHour} .endHour=${this.endHour}></tl-grid>
|
|
489
|
+
</div>
|
|
490
|
+
${this.resources.map(e=>{let a=this._validItems.filter(t=>t.resourceId===e.id),o=this._subRowMap(e.id),s=this._rowHeight(e.id),c=i?.resourceId===e.id;return A`
|
|
491
|
+
<div
|
|
492
|
+
class="resource-row"
|
|
493
|
+
style="height: ${s}px"
|
|
494
|
+
data-resource-id=${e.id}
|
|
495
|
+
>
|
|
496
|
+
<div class="resource-label">
|
|
497
|
+
${this.showAvatar?e.avatar?A`<img class="avatar" src=${e.avatar} alt="" />`:A`<div class="avatar-initials" style="background:${this._resourceColor(e.id)}">${this._initials(e.name)}</div>`:M}
|
|
498
|
+
<div class="resource-info">
|
|
499
|
+
<div class="resource-name">${e.name}</div>
|
|
500
|
+
${this.showEventCount?A`<div class="resource-count">${a.length} event${a.length===1?``:`s`}</div>`:M}
|
|
501
|
+
</div>
|
|
502
|
+
</div>
|
|
503
|
+
<div
|
|
504
|
+
class="resource-content${this.creatable&&!this.readonly?` creatable`:``}"
|
|
505
|
+
@pointerdown=${this.creatable&&!this.readonly?t=>this._onContentPointerDown(e.id,t):M}
|
|
506
|
+
>
|
|
507
|
+
${n?A`<div class="now-line" style="left: ${t}%"></div>`:M}
|
|
508
|
+
${a.map(e=>{let t=this._clipToDay(e),n=K(t.start,this.startHour,this.endHour),i=K(t.end,this.startHour,this.endHour)-n,a=o.get(e.id)??0,s=r?.item.id===e.id;return A`
|
|
509
|
+
<tl-item
|
|
510
|
+
.item=${e}
|
|
511
|
+
.dragEnabled=${this.draggable}
|
|
512
|
+
.resizable=${this.resizable}
|
|
513
|
+
.showTime=${this.showTime}
|
|
514
|
+
.showTooltip=${this.showTooltip}
|
|
515
|
+
.readonly=${this.readonly}
|
|
516
|
+
.renderContent=${this.renderItem}
|
|
517
|
+
class=${s?`dragging`:``}
|
|
518
|
+
style="left: ${n}%; width: ${i}%; top: ${a*Q}px; height: ${Q}px"
|
|
519
|
+
></tl-item>
|
|
520
|
+
`})}
|
|
521
|
+
${r?.targetResourceId===e.id?A`
|
|
522
|
+
<div
|
|
523
|
+
class="ghost"
|
|
524
|
+
style="
|
|
525
|
+
left: ${K(r.targetStart,this.startHour,this.endHour)}%;
|
|
526
|
+
width: ${K(r.targetEnd,this.startHour,this.endHour)-K(r.targetStart,this.startHour,this.endHour)}%;
|
|
527
|
+
top: 4px;
|
|
528
|
+
height: ${Q-8}px;
|
|
529
|
+
background-color: ${r.item.color};
|
|
530
|
+
"
|
|
531
|
+
></div>
|
|
532
|
+
`:M}
|
|
533
|
+
${c?A`
|
|
534
|
+
<div
|
|
535
|
+
class="create-ghost"
|
|
536
|
+
style="
|
|
537
|
+
left: ${K(i.previewStart,this.startHour,this.endHour)}%;
|
|
538
|
+
width: ${K(i.previewEnd,this.startHour,this.endHour)-K(i.previewStart,this.startHour,this.endHour)}%;
|
|
539
|
+
top: 4px;
|
|
540
|
+
height: ${Q-8}px;
|
|
541
|
+
"
|
|
542
|
+
></div>
|
|
543
|
+
`:M}
|
|
544
|
+
</div>
|
|
545
|
+
</div>
|
|
546
|
+
`})}
|
|
547
|
+
</div>
|
|
548
|
+
</div>
|
|
549
|
+
${this._ctxState?this._renderCtxMenu():M}
|
|
550
|
+
${this._editDraft?this._renderModal():M}
|
|
551
|
+
`}_renderNav(){let e=this.date.toLocaleDateString([],{weekday:`long`,year:`numeric`,month:`long`,day:`numeric`});return A`
|
|
552
|
+
<div class="nav-bar">
|
|
553
|
+
${this.showDateNav?A`
|
|
554
|
+
<div class="nav-group">
|
|
555
|
+
<button class="nav-btn" @click=${()=>this._navigate(-1)}>‹</button>
|
|
556
|
+
<button class="nav-date" @click=${this._openDatePicker}>${e}</button>
|
|
557
|
+
<button class="nav-btn" @click=${()=>this._navigate(1)}>›</button>
|
|
558
|
+
</div>
|
|
559
|
+
<input
|
|
560
|
+
type="date"
|
|
561
|
+
class="nav-date-input"
|
|
562
|
+
.value=${this._toInputDate(this.date)}
|
|
563
|
+
@change=${this._onNavDateChange}
|
|
564
|
+
tabindex="-1"
|
|
565
|
+
/>
|
|
566
|
+
`:M}
|
|
567
|
+
${this.showZoomControls?A`
|
|
568
|
+
<div class="zoom-controls">
|
|
569
|
+
${[1,2,4].map(e=>A`
|
|
570
|
+
<button
|
|
571
|
+
class="zoom-btn${this.zoom===e?` active`:``}"
|
|
572
|
+
@click=${()=>{this.zoom=e}}
|
|
573
|
+
>${e}x</button>
|
|
574
|
+
`)}
|
|
575
|
+
</div>
|
|
576
|
+
`:M}
|
|
577
|
+
</div>
|
|
578
|
+
`}_openDatePicker(){let e=this.shadowRoot.querySelector(`.nav-date-input`);try{e.showPicker()}catch{e.click()}}_navigate(e){let t=new Date(this.date);t.setDate(t.getDate()+e),this.date=t,this.dispatchEvent(new CustomEvent(`date-change`,{bubbles:!0,composed:!0,detail:{date:t}}))}_onNavDateChange(e){let t=e.target.value;if(!t)return;let[n,r,i]=t.split(`-`).map(Number),a=new Date(n,r-1,i);this.date=a,this.dispatchEvent(new CustomEvent(`date-change`,{bubbles:!0,composed:!0,detail:{date:a}}))}_renderCtxMenu(){let e=this._ctxState;return A`
|
|
579
|
+
<div class="ctx-backdrop" @pointerdown=${this._closeCtxMenu}></div>
|
|
580
|
+
<div class="ctx-menu" style="top: ${e.y}px; left: ${e.x}px">
|
|
581
|
+
${this.editable?A`
|
|
582
|
+
<button class="ctx-item" @click=${this._ctxEdit}>Edit</button>
|
|
583
|
+
<div class="ctx-separator"></div>
|
|
584
|
+
`:M}
|
|
585
|
+
<button class="ctx-item danger" @click=${this._ctxDelete}>Delete</button>
|
|
586
|
+
<div class="ctx-separator"></div>
|
|
587
|
+
<button class="ctx-item" @click=${this._closeCtxMenu}>Close</button>
|
|
588
|
+
</div>
|
|
589
|
+
`}_ctxEdit(){if(!this._ctxState)return;let{item:e}=this._ctxState;this._ctxState=null,this._openEditModal(e)}_ctxDelete(){if(!this._ctxState)return;let{item:e}=this._ctxState;this._ctxState=null;let t=this.items.filter(t=>t.id!==e.id);this.dispatchEvent(new CustomEvent(`change`,{bubbles:!0,composed:!0,detail:{items:t}}))}_closeCtxMenu(){this._ctxState=null}_renderModal(){let e=this._editDraft,t=new Date(`${e.startDate}T${e.startTime}`),n=new Date(`${e.endDate}T${e.endTime}`),r=isNaN(t.getTime())||isNaN(n.getTime())||t>=n;return A`
|
|
590
|
+
<div class="modal-backdrop" @pointerdown=${this._onBackdropDown}>
|
|
591
|
+
<div class="modal" @pointerdown=${e=>e.stopPropagation()}>
|
|
592
|
+
<p class="modal-title">Edit item</p>
|
|
593
|
+
<div class="modal-fields">
|
|
594
|
+
<div class="modal-field">
|
|
595
|
+
<span class="modal-label">Name</span>
|
|
596
|
+
<input class="modal-input" type="text" .value=${e.name}
|
|
597
|
+
@input=${e=>this._patch({name:e.target.value})} />
|
|
598
|
+
</div>
|
|
599
|
+
<div class="modal-field">
|
|
600
|
+
<span class="modal-label">Resource</span>
|
|
601
|
+
<select class="modal-input"
|
|
602
|
+
.value=${e.resourceId}
|
|
603
|
+
@change=${e=>this._patch({resourceId:e.target.value})}>
|
|
604
|
+
${this.resources.map(t=>A`
|
|
605
|
+
<option value=${t.id} ?selected=${t.id===e.resourceId}>${t.name}</option>
|
|
606
|
+
`)}
|
|
607
|
+
</select>
|
|
608
|
+
</div>
|
|
609
|
+
<div class="modal-field">
|
|
610
|
+
<span class="modal-label">Start</span>
|
|
611
|
+
<div class="modal-row">
|
|
612
|
+
<input class="modal-input" type="date" .value=${e.startDate}
|
|
613
|
+
@change=${e=>this._patch({startDate:e.target.value})} />
|
|
614
|
+
<input class="modal-input" type="time" .value=${e.startTime}
|
|
615
|
+
@change=${e=>this._patch({startTime:e.target.value})} />
|
|
616
|
+
</div>
|
|
617
|
+
</div>
|
|
618
|
+
<div class="modal-field">
|
|
619
|
+
<span class="modal-label">End</span>
|
|
620
|
+
<div class="modal-row">
|
|
621
|
+
<input class="modal-input" type="date" .value=${e.endDate}
|
|
622
|
+
@change=${e=>this._patch({endDate:e.target.value})} />
|
|
623
|
+
<input class="modal-input" type="time" .value=${e.endTime}
|
|
624
|
+
@change=${e=>this._patch({endTime:e.target.value})} />
|
|
625
|
+
</div>
|
|
626
|
+
</div>
|
|
627
|
+
<div class="modal-error">
|
|
628
|
+
${r&&e.startTime&&e.endTime?`End must be after start.`:``}
|
|
629
|
+
</div>
|
|
630
|
+
</div>
|
|
631
|
+
<div class="modal-actions">
|
|
632
|
+
<button class="modal-btn" @click=${this._closeModal}>Cancel</button>
|
|
633
|
+
<button class="modal-btn modal-btn-primary" ?disabled=${r} @click=${this._saveModal}>Save</button>
|
|
634
|
+
</div>
|
|
635
|
+
</div>
|
|
636
|
+
</div>
|
|
637
|
+
`}_openEditModal(e){this._editDraft={id:e.id,name:e.name,resourceId:e.resourceId,startDate:this._toInputDate(e.start),startTime:this._toInputTime(e.start),endDate:this._toInputDate(e.end),endTime:this._toInputTime(e.end)}}_patch(e){this._editDraft={...this._editDraft,...e}}_closeModal(){this._editDraft=null}_onBackdropDown(){this._closeModal()}_saveModal(){let e=this._editDraft,t=new Date(`${e.startDate}T${e.startTime}`),n=new Date(`${e.endDate}T${e.endTime}`);if(isNaN(t.getTime())||isNaN(n.getTime())||t>=n)return;let r=this.items.map(r=>r.id===e.id?{...r,name:e.name,resourceId:e.resourceId,start:t,end:n}:r);this.dispatchEvent(new CustomEvent(`change`,{bubbles:!0,composed:!0,detail:{items:r}})),this._editDraft=null}_onItemDragStart(e){if(this.readonly||!this.draggable)return;e.stopPropagation();let{item:t,pointerId:n,clientX:r}=e.detail,i=this._getContentRect();i&&(this._dragState={item:t,pointerId:n,offsetPercent:(r-i.left)/i.width*100-K(t.start,this.startHour,this.endHour),targetResourceId:t.resourceId,targetStart:new Date(t.start),targetEnd:new Date(t.end),mode:`move`},this.dispatchEvent(new CustomEvent(`item-dragstart`,{bubbles:!0,composed:!0,detail:{item:t}})),this.shadowRoot.querySelector(`.wrapper`).setPointerCapture(n))}_onItemResizeStart(e){if(this.readonly||!this.resizable)return;e.stopPropagation();let{item:t,edge:n,pointerId:r}=e.detail;this._dragState={item:t,pointerId:r,offsetPercent:0,targetResourceId:t.resourceId,targetStart:new Date(t.start),targetEnd:new Date(t.end),mode:n===`left`?`resize-left`:`resize-right`},this.dispatchEvent(new CustomEvent(`item-resizestart`,{bubbles:!0,composed:!0,detail:{item:t}})),this.shadowRoot.querySelector(`.wrapper`).setPointerCapture(r)}_onContentPointerDown(e,t){if(t.target!==t.currentTarget||t.button!==0||this._dragState||this._createState||this._createPending)return;t.preventDefault();let n=t.currentTarget.getBoundingClientRect(),r=J(q(G((t.clientX-n.left)/n.width*100,0,100),this.startHour,this.endHour,this.date),this.snapMinutes);this._createPending={pointerId:t.pointerId,resourceId:e,anchorTime:r,lastX:t.clientX},this.shadowRoot.querySelector(`.wrapper`).setPointerCapture(t.pointerId),this._createHoldTimer=window.setTimeout(()=>{if(!this._createPending)return;let{pointerId:e,resourceId:t,anchorTime:n,lastX:r}=this._createPending;this._createPending=null;let i=this._getContentRect(),a=n,o=new Date(n.getTime()+this.snapMinutes*6e4);if(i){let e=J(q(G((r-i.left)/i.width*100,0,100),this.startHour,this.endHour,this.date),this.snapMinutes),t=e<=n?e:n,s=e>n?e:n,c=new Date(t.getTime()+this.snapMinutes*6e4);a=t,o=s>c?s:c}this._createState={pointerId:e,resourceId:t,anchorTime:n,previewStart:a,previewEnd:o}},Oe)}_cancelCreatePending(){clearTimeout(this._createHoldTimer),this._createPending=null}_onPointerMove(e){if(this._createPending&&e.pointerId===this._createPending.pointerId){this._createPending.lastX=e.clientX;return}if(this._dragState&&e.pointerId===this._dragState.pointerId){e.preventDefault();let t=this._getContentRect();if(!t)return;let{item:n,mode:r}=this._dragState,i=(e.clientX-t.left)/t.width*100,a=this.minDurationMinutes>0?this.minDurationMinutes*6e4:this.snapMinutes*6e4,o=this.maxDurationMinutes>0?this.maxDurationMinutes*6e4:1/0;if(r===`move`){let t=n.end.getTime()-n.start.getTime(),r=q(G(i-this._dragState.offsetPercent,0,100),this.startHour,this.endHour,this.date);r=J(r,this.snapMinutes);let a=new Date(r.getTime()+t),o=new Date(this.date);o.setHours(this.endHour,0,0,0),a>o&&(a=o,r=new Date(a.getTime()-t));let s=this._resourceIdAtY(e.clientY)??this._dragState.targetResourceId;this._dragState={...this._dragState,targetResourceId:s,targetStart:r,targetEnd:a}}else if(r===`resize-left`){let e=q(G(i,0,100),this.startHour,this.endHour,this.date);e=J(e,this.snapMinutes);let t=this._dragState.targetEnd,n=new Date(t.getTime()-o),r=new Date(t.getTime()-a);e<n&&(e=n),e>r&&(e=r),this._dragState={...this._dragState,targetStart:e}}else if(r===`resize-right`){let e=new Date(this.date);e.setHours(this.endHour,0,0,0);let t=q(G(i,0,100),this.startHour,this.endHour,this.date);t=J(t,this.snapMinutes),t>e&&(t=e);let n=this._dragState.targetStart,r=new Date(n.getTime()+a),s=new Date(n.getTime()+o);t<r&&(t=r),t>s&&(t=s),this._dragState={...this._dragState,targetEnd:t}}}else if(this._createState&&e.pointerId===this._createState.pointerId){e.preventDefault();let t=this._getContentRect();if(!t)return;let n=J(q(G((e.clientX-t.left)/t.width*100,0,100),this.startHour,this.endHour,this.date),this.snapMinutes),r=this._createState.anchorTime,i=n<=r?n:r,a=n>r?n:r,o=new Date(i.getTime()+this.snapMinutes*6e4);this._createState={...this._createState,previewStart:i,previewEnd:a>o?a:o}}}_onPointerUp(e){if(this._createPending&&e.pointerId===this._createPending.pointerId){this._cancelCreatePending();return}if(this._dragState&&e.pointerId===this._dragState.pointerId){let{item:t,targetResourceId:n,targetStart:r,targetEnd:i,mode:a}=this._dragState,o=this._resourceIdAtY(e.clientY),s=a===`move`&&o!==null?n:t.resourceId,c=o!==null||a!==`move`?r:t.start,l=o!==null||a!==`move`?i:t.end,u=this.items.map(e=>e.id===t.id?{...e,resourceId:s,start:c,end:l}:e);this.dispatchEvent(new CustomEvent(`change`,{bubbles:!0,composed:!0,detail:{items:u}})),a===`move`?this.dispatchEvent(new CustomEvent(`item-dragend`,{bubbles:!0,composed:!0,detail:{item:t,resourceId:s,start:c,end:l}})):this.dispatchEvent(new CustomEvent(`item-resizeend`,{bubbles:!0,composed:!0,detail:{item:t,start:c,end:l}})),this._dragState=null}else if(this._createState&&e.pointerId===this._createState.pointerId){let{resourceId:e,previewStart:t,previewEnd:n}=this._createState;this._createState=null,this.dispatchEvent(new CustomEvent(`item-create`,{bubbles:!0,composed:!0,detail:{resourceId:e,start:t,end:n}}))}}_onItemClick(e){e.stopPropagation(),this.dispatchEvent(new CustomEvent(`item-click`,{bubbles:!0,composed:!0,detail:{item:e.detail.item}}))}_onItemDblClick(e){e.stopPropagation(),this.dispatchEvent(new CustomEvent(`item-dblclick`,{bubbles:!0,composed:!0,detail:{item:e.detail.item}})),!this.readonly&&this.editable&&this._openEditModal(e.detail.item)}_onItemHover(e){e.stopPropagation(),this.dispatchEvent(new CustomEvent(`item-hover`,{bubbles:!0,composed:!0,detail:{item:e.detail.item,type:e.detail.type}}))}_onItemContextMenu(e){e.stopPropagation(),this._ctxState={item:e.detail.item,x:e.detail.x,y:e.detail.y},this.dispatchEvent(new CustomEvent(`item-contextmenu`,{bubbles:!0,composed:!0,detail:{item:e.detail.item,x:e.detail.x,y:e.detail.y}}))}_onItemKeyMove(e){if(this.readonly||!this.draggable)return;e.stopPropagation();let{item:t,direction:n}=e.detail,r=(n===`left`?-1:1)*this.snapMinutes*6e4,i=new Date(this.date);i.setHours(this.startHour,0,0,0);let a=new Date(this.date);a.setHours(this.endHour,0,0,0);let o=new Date(t.start.getTime()+r),s=new Date(t.end.getTime()+r);o<i&&(o=i,s=new Date(i.getTime()+(t.end.getTime()-t.start.getTime()))),s>a&&(s=a,o=new Date(a.getTime()-(t.end.getTime()-t.start.getTime())));let c=this.items.map(e=>e.id===t.id?{...e,start:o,end:s}:e);this.dispatchEvent(new CustomEvent(`change`,{bubbles:!0,composed:!0,detail:{items:c}}))}_toInputDate(e){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}_toInputTime(e){return`${String(e.getHours()).padStart(2,`0`)}:${String(e.getMinutes()).padStart(2,`0`)}`}_getContentRect(){return this.shadowRoot?.querySelector(`.resource-content`)?.getBoundingClientRect()??null}_resourceIdAtY(e){let t=this.shadowRoot?.querySelectorAll(`.resource-row`);if(!t)return null;for(let n of t){let t=n.getBoundingClientRect();if(e>=t.top&&e<t.bottom)return n.dataset.resourceId??null}return null}};Y([U({attribute:!1})],$.prototype,`resources`,void 0),Y([U({attribute:!1})],$.prototype,`items`,void 0),Y([U({type:Number})],$.prototype,`startHour`,void 0),Y([U({type:Number})],$.prototype,`endHour`,void 0),Y([U({type:Number})],$.prototype,`snapMinutes`,void 0),Y([U({attribute:!1})],$.prototype,`date`,void 0),Y([U({type:Boolean})],$.prototype,`draggable`,void 0),Y([U({type:Boolean})],$.prototype,`resizable`,void 0),Y([U({type:Boolean})],$.prototype,`readonly`,void 0),Y([U({type:Boolean})],$.prototype,`showTime`,void 0),Y([U({type:Number})],$.prototype,`minDurationMinutes`,void 0),Y([U({type:Number})],$.prototype,`maxDurationMinutes`,void 0),Y([U({type:Number})],$.prototype,`zoom`,void 0),Y([U({type:Boolean})],$.prototype,`showNav`,void 0),Y([U({type:Boolean})],$.prototype,`creatable`,void 0),Y([U({attribute:!1})],$.prototype,`renderItem`,void 0),Y([U({type:Boolean})],$.prototype,`showAvatar`,void 0),Y([U({type:Boolean})],$.prototype,`showEventCount`,void 0),Y([U({type:Boolean})],$.prototype,`showTooltip`,void 0),Y([U({type:Boolean})],$.prototype,`showNowLine`,void 0),Y([U({type:Boolean})],$.prototype,`showZoomControls`,void 0),Y([U({type:Boolean})],$.prototype,`showDateNav`,void 0),Y([U({type:Boolean})],$.prototype,`editable`,void 0),Y([W()],$.prototype,`_dragState`,void 0),Y([W()],$.prototype,`_createState`,void 0),Y([W()],$.prototype,`_ctxState`,void 0),Y([W()],$.prototype,`_now`,void 0),Y([W()],$.prototype,`_editDraft`,void 0),$=Y([H(`timeline-scheduler`)],$),Object.defineProperty(exports,`TimelineScheduler`,{enumerable:!0,get:function(){return $}});
|