Skip to content

Commit

Permalink
Merge pull request #16622 from itisAliRH/create-gdatetime-component
Browse files Browse the repository at this point in the history
Create `GDateTime` component
  • Loading branch information
davelopez authored Sep 12, 2023
2 parents 3c60283 + 1b671cd commit af8edd2
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
43 changes: 43 additions & 0 deletions client/src/components/GDateTime.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { getLocalVue } from "@tests/jest/helpers";
import { mount } from "@vue/test-utils";

import GDateTime from "./GDateTime.vue";

const localVue = getLocalVue(true);

async function mountGDateTime(props: object) {
const wrapper = mount(GDateTime as object, {
propsData: {
...props,
},
localVue,
});

return wrapper;
}

describe("GDateTime.vue", () => {
it("emits updated date when input changes", async () => {
const wrapper = await mountGDateTime({
value: new Date("1970-01-01T00:00:00"),
});

const dateInput = wrapper.find('input[type="date"]');
await dateInput.setValue("2023-08-30");

expect(wrapper.emitted()).toHaveProperty("input");
expect(wrapper.emitted()?.["input"]?.[0]?.[0]).toEqual(new Date("2023-08-30T00:00:00"));
});

it("emits updated time when input changes", async () => {
const wrapper = await mountGDateTime({
value: new Date("1970-01-01T00:00:00"),
});

const timeInput = wrapper.find('input[type="time"]');
await timeInput.setValue("12:30");

expect(wrapper.emitted()).toHaveProperty("input");
expect(wrapper.emitted()?.["input"]?.[0]?.[0]).toEqual(new Date("1970-01-01T12:30:00"));
});
});
71 changes: 71 additions & 0 deletions client/src/components/GDateTime.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<script setup lang="ts">
import { BFormInput, BInputGroup } from "bootstrap-vue";
import { Tuple } from "types/utilityTypes";
import { computed } from "vue";
const props = defineProps<{
value: Date;
}>();
const emit = defineEmits<{
(e: "input", value: Date): void;
}>();
const date = computed(() => {
const year = props.value.getFullYear().toString().padStart(4, "0");
const month = (props.value.getMonth() + 1).toString().padStart(2, "0");
const day = props.value.getDate().toString().padStart(2, "0");
return `${year}-${month}-${day}`;
});
const time = computed(() => {
const hours = props.value.getHours().toString().padStart(2, "0");
const minutes = props.value.getMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
});
function updateDate(newDate: string) {
const matches = newDate.match(/(\d{4})-(\d{2})-(\d{2})/);
if (matches?.length && matches.length >= 4) {
const [_v, year, month, day] = matches as Tuple<4, string>;
const date = new Date(props.value);
try {
date.setFullYear(parseInt(year));
date.setDate(1);
date.setMonth(0);
date.setMonth(parseInt(month) - 1);
date.setDate(parseInt(day));
} finally {
emit("input", date);
}
}
}
function updateTime(newTime: string) {
const matches = newTime.match(/(\d{2}):(\d{2})/);
if (matches?.length && matches.length >= 3) {
const [_v, hours, minutes] = matches as Tuple<3, string>;
const date = new Date(props.value);
try {
date.setHours(parseInt(hours), parseInt(minutes));
} finally {
emit("input", date);
}
}
}
</script>

<template>
<BInputGroup>
<BFormInput :value="date" type="date" @input="updateDate" />
<BFormInput :value="time" type="time" @input="updateTime" />
</BInputGroup>
</template>

0 comments on commit af8edd2

Please sign in to comment.