Skip to content

Commit

Permalink
calculate date with Luxon and use ember-intl to format days without time
Browse files Browse the repository at this point in the history
  • Loading branch information
jelhan committed Aug 19, 2023
1 parent 2cbb75d commit 796a1d1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 86 deletions.
58 changes: 23 additions & 35 deletions app/models/option.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { attr } from '@ember-data/model';
import { assert } from '@ember/debug';
import { isEmpty } from '@ember/utils';
import moment from 'moment';
import { DateTime } from 'luxon';
import Fragment from 'ember-data-model-fragments/fragment';
import { fragmentOwner } from 'ember-data-model-fragments/attributes';
import {
Expand Down Expand Up @@ -73,6 +74,26 @@ export default class Option extends Fragment.extend(Validations) {
// working based on a property of the model.
isPartiallyFilled = false;

get datetime() {
const { title } = this;

if (isEmpty(title)) {
return null;
}

return DateTime.fromISO(title);
}

get day() {
const { datetime } = this;

if (!datetime) {
return null;
}

return datetime.toISODate();
}

@computed('title')
get date() {
const allowedFormats = [
Expand All @@ -96,46 +117,13 @@ export default class Option extends Fragment.extend(Validations) {
return moment(value, format, true);
}

@computed('date')
get day() {
const date = this.date;
if (!moment.isMoment(date)) {
return null;
}
return date.format('YYYY-MM-DD');
}

@computed('date', 'intl.primaryLocale')
get dayFormatted() {
let date = this.date;
if (!moment.isMoment(date)) {
return null;
}

const locale = this.get('intl.primaryLocale');
const format = moment.localeData(locale)
.longDateFormat('LLLL')
.replace(
moment.localeData(locale).longDateFormat('LT'), '')
.trim();

// momentjs object caches the locale on creation
if (date.locale() !== locale) {
// we clone the date to allow adjusting timezone without changing the object
date = date.clone();
date.locale(locale);
}

return date.format(format);
}

@computed('title')
@computed('date', 'title.length')
get hasTime() {
return moment.isMoment(this.date) &&
this.title.length === 'YYYY-MM-DDTHH:mm:ss.SSSZ'.length;
}

@computed('date')
@computed('date', 'title')
get time() {
const date = this.date;
if (!moment.isMoment(date)) {
Expand Down
48 changes: 35 additions & 13 deletions app/templates/components/create-options-datetime.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,29 @@
data-test-day={{date.day}}
>
<form.element
@label={{date.dayFormatted}}
{{!
TODO: Simplify to dateStyle="full" after upgrading to Ember Intl v6
}}
@label={{format-date
date.day
weekday="long"
day="numeric"
month="long"
year="numeric"
}}
{{!
show label only if it differ from label before
Nested-helpers are called first and object-at requires a positive integer
but returns undefined if an element with the passed in index does not exist.
Therefore we pass in array length if index is null. Cause index starting
by zero there can't be any element with an index === array.length.
}}
@invisibleLabel={{eq date.dayFormatted (get (object-at (if index (sub index 1) @dates.length) @dates) "dayFormatted")}}
@invisibleLabel={{eq
date.day
(get
(object-at (if index (sub index 1) @dates.length) @dates) "day"
)
}}
@model={{date}}
@property="time"
class="option"
Expand All @@ -47,14 +61,11 @@
@placeholder="00:00"
@type="time"
@value={{el.value}}

{{! focus input if it's the first one }}
{{autofocus enabled=(eq index 0)}}

{{! run validation for partially filled input on focusout event }}
{{on "focusout" (fn this.validateInput date)}}

{{!--
{{!
Validation for partially input field must be reset if input is cleared.
But `@onChange` is not called and `focusout` event not triggered in that
scenario. Need to listen to additional events to ensure that partially
Expand All @@ -67,10 +78,9 @@
Firefox does not consider partially time input as invalid, Edge prevents
partially filling in first place and Desktop Safari as well as IE 11
do not support `<input type="time">`.
--}}
}}
{{on "focusin" (fn this.updateInputValidation date)}}
{{on "keyup" (fn this.updateInputValidation date)}}

id={{el.id}}
/>
<div class="input-group-append">
Expand All @@ -81,8 +91,14 @@
{{! disable delete button if there is only one option }}
disabled={{lte @dates.length 1}}
>
<span class="oi oi-trash" title={{t "create.options.button.delete.label"}} aria-hidden="true"></span>
<span class="sr-only">{{t "create.options.button.delete.label"}}</span>
<span
class="oi oi-trash"
title={{t "create.options.button.delete.label"}}
aria-hidden="true"
></span>
<span class="sr-only">{{t
"create.options.button.delete.label"
}}</span>
</BsButton>
</div>
</div>
Expand All @@ -93,8 +109,14 @@
@size="sm"
class="add cr-option-menu__button cr-option-menu__add-button float-left"
>
<span class="oi oi-plus" title={{t "create.options.button.add.label"}} aria-hidden="true"></span>
<span class="sr-only">{{t "create.options.button.add.label"}}</span>
<span
class="oi oi-plus"
title={{t "create.options.button.add.label"}}
aria-hidden="true"
></span>
<span class="sr-only">{{t
"create.options.button.add.label"
}}</span>
</BsButton>
</form.element>
</div>
Expand Down Expand Up @@ -122,4 +144,4 @@
</div>
</div>
</BsForm>
</div>
</div>
38 changes: 0 additions & 38 deletions tests/unit/models/option-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,44 +123,6 @@ module('Unit | Model | option', function(hooks) {
);
});

test('dayFormatted property (get)', function(assert) {
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
title: '2015-01-01'
}));
assert.equal(
option.get('dayFormatted'),
'Thursday, January 1, 2015',
'returns formatted date if title is ISO 8601 day string'
);

run(() => {
option.set('title', moment('2015-01-01').toISOString());
});
assert.equal(
option.get('dayFormatted'),
'Thursday, January 1, 2015',
'returns formatted date if title is ISO 8601 datetime string'
);

run(() => {
option.set('intl.locale', 'de');
});
assert.equal(
option.get('dayFormatted'),
'Donnerstag, 1. Januar 2015',
'observes locale changes'
);

run(() => {
option.set('title', 'abc');
});
assert.equal(
option.get('dayFormatted'),
undefined,
'returns undfined if title is not a valid ISO 8601 string'
);
});

test('hasTime property', function(assert) {
let option = run(() => this.owner.lookup('service:store').createRecord('option', {
title: '2015-01-01T11:11:00.000Z'
Expand Down

0 comments on commit 796a1d1

Please sign in to comment.