diff --git a/.scripts/build.mjs b/.scripts/build.mjs index 8b38407ed..5a24cfdfe 100644 --- a/.scripts/build.mjs +++ b/.scripts/build.mjs @@ -1,19 +1,19 @@ #!/usr/bin/env zx -import isCI from 'is-ci'; +import isCI from 'is-ci' const { b = isCI, // pass `-b` to build if you want it to run browserslist update outside of CI environment -} = argv; +} = argv if (b) { // Update browserslist - await $`npx browserslist@latest --update-db`; + await $`npx update-browserslist-db@latest` } console.log(chalk.blue('[BEGIN BUILD]')) console.log(chalk.blue('Building js')) // build distributables -await $`NODE_ENV=production rollup -c`; +await $`NODE_ENV=production rollup -c` console.log(chalk.blue(`Compiling 'lib' js files`)) // build files used for overrides await $`NODE_ENV=production RBC_CJS_BUILD=true babel src --out-dir lib` @@ -22,7 +22,10 @@ console.log(chalk.blue(`Copying SASS files to 'lib'`)) await fs.copy('./src/sass', './lib/sass') console.log(chalk.blue(`...and the 'Add-on' SASS`)) // don't forget DnD -await fs.copy('./src/addons/dragAndDrop/styles.scss', './lib/addons/dragAndDrop/styles.scss') +await fs.copy( + './src/addons/dragAndDrop/styles.scss', + './lib/addons/dragAndDrop/styles.scss' +) console.log(chalk.blue('Now we will build some CSS')) // Compile SASS from './lib' to get sourcemaps console.log(chalk.blue('Compile base styles')) diff --git a/src/Month.js b/src/Month.js index 997f48fd8..9fc1d597d 100644 --- a/src/Month.js +++ b/src/Month.js @@ -16,7 +16,7 @@ import DateContentRow from './DateContentRow' import Header from './Header' import DateHeader from './DateHeader' -import { inRange, sortEvents } from './utils/eventLevels' +import { inRange, sortWeekEvents } from './utils/eventLevels' let eventsForWeek = (evts, start, end, accessors, localizer) => evts.filter((e) => inRange(e, start, end, accessors, localizer)) @@ -124,7 +124,7 @@ class MonthView extends React.Component { localizer ) - weeksEvents.sort((a, b) => sortEvents(a, b, accessors, localizer)) + const sorted = sortWeekEvents(weeksEvents, accessors, localizer) return ( value.getTimezoneOffset()) + spec.getTimezoneOffset || ((value) => value.getTimezoneOffset()) this.getDstOffset = spec.getDstOffset || getDstOffset this.getTotalMin = spec.getTotalMin || getTotalMin this.getMinutesFromMidnight = diff --git a/src/localizers/dayjs.js b/src/localizers/dayjs.js index 4f8787418..618a069d2 100644 --- a/src/localizers/dayjs.js +++ b/src/localizers/dayjs.js @@ -298,6 +298,12 @@ export default function (dayjsLib) { return djEnd.isSameOrAfter(djLast, 'minutes') } + function daySpan(start, end) { + const startDay = dayjs(start) + const endDay = dayjs(end) + return endDay.diff(startDay, 'day') + } + // These two are used by eventLevels function sortEvents({ evtA: { start: aStart, end: aEnd, allDay: aAllDay }, @@ -305,13 +311,13 @@ export default function (dayjsLib) { }) { const startSort = +startOf(aStart, 'day') - +startOf(bStart, 'day') - const durA = diff(aStart, ceil(aEnd, 'day'), 'day') + const durA = daySpan(aStart, aEnd) - const durB = diff(bStart, ceil(bEnd, 'day'), 'day') + const durB = daySpan(bStart, bEnd) return ( startSort || // sort by start Day first - Math.max(durB, 1) - Math.max(durA, 1) || // events spanning multiple days go first + durB - durA || // events spanning multiple days go first !!bAllDay - !!aAllDay || // then allDay single day events +aStart - +bStart || // then sort by start time *don't need dayjs conversion here +aEnd - +bEnd // then sort by end time *don't need dayjs conversion here either diff --git a/src/localizers/luxon.js b/src/localizers/luxon.js index 726f62554..cfc20bf26 100644 --- a/src/localizers/luxon.js +++ b/src/localizers/luxon.js @@ -308,6 +308,12 @@ export default function (DateTime, { firstDayOfWeek = 7 } = {}) { return gte(end, last) } + function daySpan(start, end) { + const dtStart = DateTime.fromJSDate(start) + const dtEnd = DateTime.fromJSDate(end) + return dtEnd.diff(dtStart).as('days') + } + // These two are used by eventLevels function sortEvents({ evtA: { start: aStart, end: aEnd, allDay: aAllDay }, @@ -315,13 +321,13 @@ export default function (DateTime, { firstDayOfWeek = 7 } = {}) { }) { const startSort = +startOf(aStart, 'day') - +startOf(bStart, 'day') - const durA = diff(aStart, ceil(aEnd, 'day'), 'day') + const durA = daySpan(aStart, aEnd) - const durB = diff(bStart, ceil(bEnd, 'day'), 'day') + const durB = daySpan(bStart, bEnd) return ( startSort || // sort by start Day first - Math.max(durB, 1) - Math.max(durA, 1) || // events spanning multiple days go first + durB - durA || // events spanning multiple days go first !!bAllDay - !!aAllDay || // then allDay single day events +aStart - +bStart || // then sort by start time *don't need moment conversion here +aEnd - +bEnd // then sort by end time *don't need moment conversion here either @@ -413,6 +419,7 @@ export default function (DateTime, { firstDayOfWeek = 7 } = {}) { sortEvents, inEventRange, isSameDate, + daySpan, browserTZOffset, }) } diff --git a/src/localizers/moment.js b/src/localizers/moment.js index 7652b42b8..8951d42bc 100644 --- a/src/localizers/moment.js +++ b/src/localizers/moment.js @@ -275,6 +275,13 @@ export default function (moment) { return mEnd.isSameOrAfter(mLast, 'minutes') } + function daySpan(start, end) { + const mStart = moment(start) + const mEnd = moment(end) + const dur = moment.duration(mEnd.diff(mStart)) + return dur.days() + } + // These two are used by eventLevels function sortEvents({ evtA: { start: aStart, end: aEnd, allDay: aAllDay }, @@ -282,13 +289,13 @@ export default function (moment) { }) { const startSort = +startOf(aStart, 'day') - +startOf(bStart, 'day') - const durA = diff(aStart, ceil(aEnd, 'day'), 'day') + const durA = daySpan(aStart, aEnd) - const durB = diff(bStart, ceil(bEnd, 'day'), 'day') + const durB = daySpan(bStart, bEnd) return ( startSort || // sort by start Day first - Math.max(durB, 1) - Math.max(durA, 1) || // events spanning multiple days go first + durB - durA || // events spanning multiple days go first !!bAllDay - !!aAllDay || // then allDay single day events +aStart - +bStart || // then sort by start time *don't need moment conversion here +aEnd - +bEnd // then sort by end time *don't need moment conversion here either @@ -381,6 +388,7 @@ export default function (moment) { sortEvents, inEventRange, isSameDate, + daySpan, browserTZOffset, }) } diff --git a/src/utils/eventLevels.js b/src/utils/eventLevels.js index eb04722c5..99e4a1a10 100644 --- a/src/utils/eventLevels.js +++ b/src/utils/eventLevels.js @@ -76,6 +76,28 @@ export function segsOverlap(seg, otherSegs) { ) } +export function sortWeekEvents(events, accessors, localizer) { + const base = [...events] + const multiDayEvents = [] + const standardEvents = [] + base.forEach((event) => { + const startCheck = accessors.start(event) + const endCheck = accessors.end(event) + if (localizer.daySpan(startCheck, endCheck) > 1) { + multiDayEvents.push(event) + } else { + standardEvents.push(event) + } + }) + const multiSorted = multiDayEvents.sort((a, b) => + sortEvents(a, b, accessors, localizer) + ) + const standardSorted = standardEvents.sort((a, b) => + sortEvents(a, b, accessors, localizer) + ) + return [...multiSorted, ...standardSorted] +} + export function sortEvents(eventA, eventB, accessors, localizer) { const evtA = { start: accessors.start(eventA), diff --git a/stories/resources/events.js b/stories/resources/events.js index 5554d9113..227c65a5d 100644 --- a/stories/resources/events.js +++ b/stories/resources/events.js @@ -1,13 +1,13 @@ const now = new Date() export default [ - { + /* { id: 0, title: 'All Day Event very long title', allDay: true, start: new Date(2015, 3, 0), end: new Date(2015, 3, 1), - }, + }, */ { id: 1, title: 'Long Event', @@ -33,7 +33,15 @@ export default [ id: 4, title: 'Some Event', start: new Date(2015, 3, 9, 0, 0, 0), - end: new Date(2015, 3, 10, 0, 0, 0), + end: new Date(2015, 3, 9, 0, 0, 0), + allDay: true, + }, + + { + id: 92, + title: 'Some Other Event', + start: new Date(2015, 3, 9, 8, 0, 0), + end: new Date(2015, 3, 10, 11, 30, 0), }, { id: 5, diff --git a/yarn.lock b/yarn.lock index d49aad288..c63927460 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5351,9 +5351,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001517: - version "1.0.30001519" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz#3e7b8b8a7077e78b0eb054d69e6edf5c7df35601" - integrity sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg== + version "1.0.30001585" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001585.tgz" + integrity sha512-yr2BWR1yLXQ8fMpdS/4ZZXpseBgE7o4g41x3a6AJOqZuOi+iE/WdJYAuZ6Y95i4Ohd2Y+9MzIWRR+uGABH4s3Q== capture-exit@^2.0.0: version "2.0.0"