mirror of
https://github.com/directus/directus.git
synced 2026-01-26 22:29:06 -05:00
Migrate over time-from-now composition
This commit is contained in:
@@ -58,6 +58,7 @@
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"html-loader": "^0.5.5",
|
||||
"lint-staged": "^9.5.0",
|
||||
"mockdate": "^2.0.5",
|
||||
"prettier": "^1.19.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -9384,6 +9384,11 @@ mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.1, mkdirp@~0.5.1, mkdirp@~0.5.x:
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
mockdate@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-2.0.5.tgz#70c6abf9ed4b2dae65c81dfc170dd1a5cec53620"
|
||||
integrity sha512-ST0PnThzWKcgSLyc+ugLVql45PvESt3Ul/wrdV/OPc/6Pr8dbLAIJsN1cIp41FLzbN+srVTNIRn+5Cju0nyV6A==
|
||||
|
||||
moment@^2.18.1:
|
||||
version "2.24.0"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||
@@ -10317,7 +10322,7 @@ pify@^4.0.1:
|
||||
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
|
||||
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
|
||||
|
||||
pinia@^0.0.5:
|
||||
pinia@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/pinia/-/pinia-0.0.5.tgz#e95fde7c3de5cdef1d4bd71fa0d9c3110862c641"
|
||||
integrity sha512-EF3LpCYsA1VSm9EeCK87UHA66NFM/7++D0qnWTzSPgQ+UKoUQytWsXat777bj9WDzjNELxKlyP3Ifv44IURi2g==
|
||||
|
||||
Reference in New Issue
Block a user