Skip to content

Commit

Permalink
replace Moment with Luxon in Ember Power Calendar
Browse files Browse the repository at this point in the history
  • Loading branch information
jelhan committed Aug 19, 2023
1 parent 5143a6a commit 2cbb75d
Show file tree
Hide file tree
Showing 5 changed files with 959 additions and 65 deletions.
25 changes: 16 additions & 9 deletions app/components/create-options-dates.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Component from '@ember/component';
import { isArray } from '@ember/array';
import { isPresent } from '@ember/utils';
import moment from 'moment';
import { DateTime } from "luxon";

@classic
export default class CreateOptionsDates extends Component {
Expand All @@ -20,41 +21,47 @@ export default class CreateOptionsDates extends Component {
.map(({ date }) => date)
// filter out invalid
.filter(moment.isMoment)
// convert to DateTime used by Luxon
.map((dateAsMoment) => DateTime.fromISO(dateAsMoment.toISOString()))
.toArray();
}

@computed('calendarCenter')
get calendarCenterNext() {
return moment(this.calendarCenter).add(1, 'months');
return this.calendarCenter.plus({ months: 1 });
}

@action
daysSelected({ moment: newMoments }) {
daysSelected({ datetime: newDatesAsLuxonDateTime }) {
let { options } = this;

if (!isArray(newMoments)) {
if (!isArray(newDatesAsLuxonDateTime)) {
// special case: all options are unselected
options.clear();
return;
}

const newDates = newDatesAsLuxonDateTime.map((dateAsLuxonDateTime) => {
return dateAsLuxonDateTime.toISODate();
});

// array of options that represent days missing in updated selection
let removedOptions = options.filter((option) => {
return !newMoments.find((newMoment) => newMoment.format('YYYY-MM-DD') === option.day);
return !newDates.find((newDate) => newDate === option.day);
});

// array of moments that aren't represented yet by an option
let addedMoments = newMoments.filter((moment) => {
return !options.find((option) => moment.format('YYYY-MM-DD') === option.day);
let addedDates = newDates.filter((newDate) => {
return !options.find((option) => newDate === option.day);
});

// remove options that represent deselected days
options.removeObjects(removedOptions);

// add options for newly selected days
let newOptions = addedMoments.map((moment) => {
let newOptions = addedDates.map((newDate) => {
return this.store.createFragment('option', {
title: moment.format('YYYY-MM-DD'),
title: newDate,
})
});
newOptions.forEach((newOption) => {
Expand Down Expand Up @@ -82,6 +89,6 @@ export default class CreateOptionsDates extends Component {
super.init(arguments);

let { selectedDays } = this;
this.set('calendarCenter', selectedDays.length >= 1 ? selectedDays[0] : moment());
this.set('calendarCenter', selectedDays.length >= 1 ? selectedDays[0] : DateTime.local());
}
}
21 changes: 12 additions & 9 deletions app/templates/components/create-options-dates.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@
as |el|
>
<div
class="
form-control
cr-h-auto
cr-pr-validation
{{if (eq el.validation "error") "is-invalid"}}
{{if (eq el.validation "success") "is-valid"}}
"
class="form-control cr-h-auto cr-pr-validation
{{if (eq el.validation 'error') 'is-invalid'}}
{{if (eq el.validation 'success') 'is-valid'}}
"
>
<div class="row">
<div class="col-12 col-md-6">
<InlineDatepicker
@center={{this.calendarCenter}}
@selectedDays={{this.selectedDays}}
@onCenterChange={{action (mut this.calendarCenter) value="moment"}}
@onCenterChange={{action
(mut this.calendarCenter)
value="datetime"
}}
@onSelect={{action "daysSelected"}}
/>
</div>
<div class="col-md-6 cr-hide-on-mobile">
<InlineDatepicker
@center={{this.calendarCenterNext}}
@selectedDays={{this.selectedDays}}
@onCenterChange={{action (mut this.calendarCenter) value="moment"}}
@onCenterChange={{action
(mut this.calendarCenter)
value="datetime"
}}
@onSelect={{action "daysSelected"}}
/>
</div>
Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"babel-eslint": "^10.1.0",
"bootstrap": "^4.3.1",
"broccoli-asset-rev": "^3.0.0",
"ember-auto-import": "^1.6.0",
"ember-auto-import": "^2.0.0",
"ember-awesome-macros": "^6.0.0",
"ember-bootstrap": "^3.0.0",
"ember-bootstrap-cp-validations": "^2.0.0",
Expand Down Expand Up @@ -69,7 +69,7 @@
"ember-moment": "^8.0.0",
"ember-page-title": "^6.0.0",
"ember-power-calendar": "^0.19.0",
"ember-power-calendar-moment": "^0.1.4",
"ember-power-calendar-luxon": "^0.4.0",
"ember-qunit": "^4.6.0",
"ember-resolver": "^8.0.0",
"ember-source": "~3.20.2",
Expand All @@ -89,7 +89,8 @@
"release-it": "^16.0.0",
"release-it-lerna-changelog": "^5.0.0",
"sass": "^1.19.0",
"sjcl": "^1.0.8"
"sjcl": "^1.0.8",
"webpack": "^5.0.0"
},
"engines": {
"node": "16.* || >=18"
Expand Down
17 changes: 8 additions & 9 deletions tests/unit/components/create-options-dates-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { isArray } from '@ember/array';
import moment from 'moment';
import { DateTime } from 'luxon';

module('Unit | Component | create options dates', function(hooks) {
setupTest(hooks);
Expand Down Expand Up @@ -31,13 +32,11 @@ module('Unit | Component | create options dates', function(hooks) {
'array length is correct'
);
assert.ok(
component.selectedDays.every((el) => {
return moment.isMoment(el);
}),
component.selectedDays.every(DateTime.isDateTime),
'array elements are moment objects'
);
assert.deepEqual(
component.selectedDays.map((el) => el.format('YYYY-MM-DD')),
component.selectedDays.map((day) => day.toISODate()),
values.slice(0, 2),
'values are correct'
);
Expand Down Expand Up @@ -65,11 +64,11 @@ module('Unit | Component | create options dates', function(hooks) {
'array length is correct'
);
assert.ok(
component.selectedDays.every(moment.isMoment),
component.selectedDays.every(DateTime.isDateTime),
'array elements are moment objects'
);
assert.deepEqual(
component.selectedDays.map((day) => day.format('YYYY-MM-DD')),
component.selectedDays.map((day) => day.toISODate()),
['2014-01-01', '2015-02-02', '2016-03-03'],
'dates are correct'
);
Expand All @@ -82,7 +81,7 @@ module('Unit | Component | create options dates', function(hooks) {

let component = this.owner.factoryFor('component:create-options-dates').create({ options });
component.actions.daysSelected.bind(component)({
moment: values.map((_) => moment(_)),
datetime: values.map((_) => DateTime.fromISO(_)),
});

assert.ok(isArray(options), 'options is still an array');
Expand Down Expand Up @@ -118,7 +117,7 @@ module('Unit | Component | create options dates', function(hooks) {
});

component.actions.daysSelected.bind(component)({
moment: merged.map((_) => moment(_)),
datetime: merged.map((_) => DateTime.fromISO(_)),
});

assert.deepEqual(
Expand All @@ -144,7 +143,7 @@ module('Unit | Component | create options dates', function(hooks) {
});

component.actions.daysSelected.bind(component)({
moment: reduced.map((_) => moment(_)),
datetime: reduced.map((_) => DateTime.fromISO(_)),
});

assert.deepEqual(
Expand Down
Loading

0 comments on commit 2cbb75d

Please sign in to comment.