mirror of
https://github.com/directus/directus.git
synced 2026-02-15 16:05:06 -05:00
Migrate over time-from-now composition
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
# Compositions
|
||||
|
||||
Compositions are reusable snippets of functionality that can be used in Vue components.
|
||||
Compositions are reusable pieces of logic that can be used inside Vue components (Composition API required).
|
||||
|
||||
## Table of Contents
|
||||
|
||||
* [Event Listener](#event-listener)
|
||||
* [Time from Now](#time-from-now)
|
||||
* [Window Size](#window-size)
|
||||
|
||||
## Event Listener
|
||||
@@ -32,6 +33,27 @@ export default createComponent({
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Time from Now
|
||||
|
||||
Returns ref string time from current datetime based on date-fns formatDistance.
|
||||
|
||||
### Usage
|
||||
|
||||
```js
|
||||
import { createComponent } from '@vue/composition-api';
|
||||
import useTimeFromNow from '@/compositions/time-from-now';
|
||||
|
||||
export default createComponent({
|
||||
setup() {
|
||||
const date = new Date('2020-01-01T13:55');
|
||||
const timeFromNow = useTimeFromNow(date);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
The composition accepts an optional second parameter that controls how often the value is update. You can set this to `0` if you don't want the value to update at all.
|
||||
|
||||
## Window Size
|
||||
|
||||
Returns a `ref` of `width` and `height` of the current window size. Updates the value on window resizes.
|
||||
|
||||
90
src/compositions/time-from-now.test.ts
Normal file
90
src/compositions/time-from-now.test.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { Ref } from '@vue/composition-api';
|
||||
import useTimeFromNow from './time-from-now';
|
||||
import mountComposition from '../../.jest/mount-composition';
|
||||
import mockdate from 'mockdate';
|
||||
|
||||
describe('Compositions / Event Listener', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockdate.reset();
|
||||
});
|
||||
|
||||
it('Formats the date relative', () => {
|
||||
const now = new Date();
|
||||
let timeAgo: Ref<string>;
|
||||
let timeAhead: Ref<string>;
|
||||
|
||||
mountComposition(() => {
|
||||
timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
|
||||
timeAhead = useTimeFromNow(new Date(now.getTime() + 5 * 60 * 1000));
|
||||
});
|
||||
|
||||
expect(timeAgo!.value).toBe('5 minutes ago');
|
||||
expect(timeAhead!.value).toBe('in 5 minutes');
|
||||
});
|
||||
|
||||
it('Updates the ref every minute by default', () => {
|
||||
mockdate.set('2020-01-01T12:00:00');
|
||||
const now = new Date();
|
||||
|
||||
const component = mountComposition(() => {
|
||||
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
|
||||
return { timeAgo };
|
||||
});
|
||||
|
||||
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
|
||||
|
||||
mockdate.set('2020-01-01T12:01:00');
|
||||
jest.runTimersToTime(60000);
|
||||
|
||||
expect(setInterval).toHaveBeenCalledTimes(1);
|
||||
|
||||
expect((component.vm as any).timeAgo).toBe('6 minutes ago');
|
||||
});
|
||||
|
||||
it('Does not automatically update if 0 is passed for autoUpdate param', () => {
|
||||
mockdate.set('2020-01-01T12:00:00');
|
||||
const now = new Date();
|
||||
|
||||
const component = mountComposition(() => {
|
||||
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000), 0);
|
||||
return { timeAgo };
|
||||
});
|
||||
|
||||
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
|
||||
|
||||
mockdate.set('2020-01-01T12:01:00');
|
||||
jest.runTimersToTime(60000);
|
||||
|
||||
expect(setInterval).toHaveBeenCalledTimes(0);
|
||||
|
||||
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
|
||||
});
|
||||
|
||||
it('Clears the interval when the component is unmounted', () => {
|
||||
mockdate.set('2020-01-01T12:00:00');
|
||||
const now = new Date();
|
||||
|
||||
const component = mountComposition(() => {
|
||||
const timeAgo = useTimeFromNow(new Date(now.getTime() - 5 * 60 * 1000));
|
||||
return { timeAgo };
|
||||
});
|
||||
|
||||
expect((component.vm as any).timeAgo).toBe('5 minutes ago');
|
||||
|
||||
mockdate.set('2020-01-01T12:01:00');
|
||||
jest.runTimersToTime(60000);
|
||||
|
||||
expect(setInterval).toHaveBeenCalledTimes(1);
|
||||
|
||||
component.destroy();
|
||||
|
||||
mockdate.set('2020-01-01T12:01:00');
|
||||
jest.runTimersToTime(60000);
|
||||
|
||||
expect(setInterval).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
26
src/compositions/time-from-now.ts
Normal file
26
src/compositions/time-from-now.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { onMounted, onUnmounted, ref } from '@vue/composition-api';
|
||||
import formatDistance from 'date-fns/formatDistance';
|
||||
|
||||
export default function useFormatDistance(date: Date | number, autoUpdate: number = 60000) {
|
||||
let interval: number;
|
||||
|
||||
const formatOptions = {
|
||||
addSuffix: true
|
||||
};
|
||||
|
||||
const formattedDate = ref(formatDistance(date, new Date(), formatOptions));
|
||||
|
||||
if (autoUpdate !== 0) {
|
||||
onMounted(() => {
|
||||
interval = setInterval(() => {
|
||||
formattedDate.value = formatDistance(date, new Date(), formatOptions);
|
||||
}, autoUpdate);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
});
|
||||
}
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
Reference in New Issue
Block a user