Migrate to Vue 3 and vite
This commit is contained in:
parent
bdf9b1637f
commit
f1995232bb
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"plugins": ["@babel/plugin-transform-runtime"],
|
|
||||||
"presets": [
|
|
||||||
[
|
|
||||||
"@babel/preset-env",
|
|
||||||
{
|
|
||||||
"useBuiltIns": "usage"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
11
index.html
Normal file
11
index.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Tool Reservations</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/index.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
28
package.json
28
package.json
@ -1,30 +1,26 @@
|
|||||||
{
|
{
|
||||||
"browserslist": [
|
|
||||||
"defaults",
|
|
||||||
"ios 9.3"
|
|
||||||
],
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "parcel src/index.html"
|
"start": "npm run dev",
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vue-tsc --noEmit && vite build",
|
||||||
|
"serve": "vite preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.8.7",
|
"@types/intl": "^1.2.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.8.3",
|
"@vitejs/plugin-legacy": "^1.6.2",
|
||||||
"@babel/preset-env": "^7.8.7",
|
"@vitejs/plugin-vue": "^1.9.4",
|
||||||
"@vue/component-compiler-utils": "^3.0.0",
|
|
||||||
"sass": "^1.23.1",
|
"sass": "^1.23.1",
|
||||||
"typescript": "^4.2.3",
|
"typescript": "^4.2.3",
|
||||||
"vue-template-compiler": "^2.6.10"
|
"vite": "^2.6.13",
|
||||||
|
"vue-tsc": "^0.28.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fullcalendar/core": "^5.6.0",
|
"@fullcalendar/core": "^5.10.0",
|
||||||
"@fullcalendar/google-calendar": "^5.6.0",
|
"@fullcalendar/google-calendar": "^5.6.0",
|
||||||
"@fullcalendar/timegrid": "^5.6.0",
|
"@fullcalendar/timegrid": "^5.6.0",
|
||||||
"@fullcalendar/vue": "^5.6.0",
|
"@fullcalendar/vue3": "^5.10.0",
|
||||||
"core-js": "^3.6.4",
|
|
||||||
"equicolor": "^1.1.0",
|
"equicolor": "^1.1.0",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"vue": "^2.6.10",
|
"vue": "^3.2.20"
|
||||||
"vue-hot-reload-api": "^2.3.4",
|
|
||||||
"vue-property-decorator": "^9.1.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
123
src/App.vue
123
src/App.vue
@ -2,18 +2,20 @@
|
|||||||
<FullCalendar ref="calendar" :options="calendarOptions"> </FullCalendar>
|
<FullCalendar ref="calendar" :options="calendarOptions"> </FullCalendar>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { Vue, Component } from 'vue-property-decorator';
|
import { ref, Ref } from 'vue';
|
||||||
import equicolor from 'equicolor/src/Equicolor';
|
import equicolor from 'equicolor/src/Equicolor';
|
||||||
|
|
||||||
import FullCalendar from '@fullcalendar/vue';
|
import '@fullcalendar/core/vdom'; // solve problem with Vite
|
||||||
|
import FullCalendar, {
|
||||||
|
EventInput,
|
||||||
|
Calendar,
|
||||||
|
CalendarOptions,
|
||||||
|
} from '@fullcalendar/vue3';
|
||||||
import timeGridPlugin from '@fullcalendar/timegrid';
|
import timeGridPlugin from '@fullcalendar/timegrid';
|
||||||
import dayGridPlugin from '@fullcalendar/daygrid';
|
import dayGridPlugin from '@fullcalendar/daygrid';
|
||||||
import googleCalendarPlugin from '@fullcalendar/google-calendar';
|
import googleCalendarPlugin from '@fullcalendar/google-calendar';
|
||||||
|
|
||||||
import { EventInput, CalendarOptions } from '@fullcalendar/core';
|
|
||||||
import { Calendar } from '@fullcalendar/core';
|
|
||||||
|
|
||||||
import { googleCalendarApiKey } from './secrets.json';
|
import { googleCalendarApiKey } from './secrets.json';
|
||||||
|
|
||||||
const calendars: { [key: string]: string } = {
|
const calendars: { [key: string]: string } = {
|
||||||
@ -31,73 +33,66 @@ const colors: string[] = equicolor.findNextColors(
|
|||||||
Object.keys(calendars).length
|
Object.keys(calendars).length
|
||||||
);
|
);
|
||||||
|
|
||||||
@Component({ components: { FullCalendar } })
|
const calendarOptions: CalendarOptions = {
|
||||||
export default class App extends Vue {
|
plugins: [timeGridPlugin, dayGridPlugin, googleCalendarPlugin],
|
||||||
calendarOptions: CalendarOptions = {
|
allDaySlot: false,
|
||||||
plugins: [timeGridPlugin, dayGridPlugin, googleCalendarPlugin],
|
nowIndicator: true,
|
||||||
allDaySlot: false,
|
initialView: 'timeGridWeek',
|
||||||
nowIndicator: true,
|
height: 'auto',
|
||||||
initialView: 'timeGridWeek',
|
googleCalendarApiKey,
|
||||||
height: 'auto',
|
slotMinTime: '8:00',
|
||||||
googleCalendarApiKey,
|
slotMaxTime: '22:00',
|
||||||
slotMinTime: '8:00',
|
businessHours: {
|
||||||
slotMaxTime: '22:00',
|
daysOfWeek: [0, 1, 2, 3, 4, 5, 6],
|
||||||
businessHours: {
|
startTime: '10:00',
|
||||||
daysOfWeek: [0, 1, 2, 3, 4, 5, 6],
|
endTime: '21:00',
|
||||||
startTime: '10:00',
|
},
|
||||||
endTime: '21:00',
|
eventSources: Object.values(calendars).map((id, idx) => {
|
||||||
},
|
return {
|
||||||
eventSources: Object.values(calendars).map((id, idx) => {
|
googleCalendarId: id,
|
||||||
return {
|
color: colors[idx],
|
||||||
googleCalendarId: id,
|
eventDataTransform: eventDataTransform,
|
||||||
color: colors[idx],
|
};
|
||||||
eventDataTransform: this.eventDataTransform,
|
}),
|
||||||
};
|
slotLabelFormat: {
|
||||||
}),
|
hour: 'numeric',
|
||||||
slotLabelFormat: {
|
minute: '2-digit',
|
||||||
hour: 'numeric',
|
hour12: false,
|
||||||
minute: '2-digit',
|
},
|
||||||
hour12: false,
|
eventTimeFormat: {
|
||||||
},
|
hour: 'numeric',
|
||||||
eventTimeFormat: {
|
minute: '2-digit',
|
||||||
hour: 'numeric',
|
hour12: false,
|
||||||
minute: '2-digit',
|
},
|
||||||
hour12: false,
|
};
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
toolFilter: string | null = null;
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const toolFilter: string | null = urlParams.get('tool');
|
||||||
|
const calendar_ref: Ref<InstanceType<typeof FullCalendar> | null> = ref(null);
|
||||||
|
|
||||||
created() {
|
// refresh data every five minutes
|
||||||
// refresh data every five minutes
|
window.setInterval(refresh, 5 * 60 * 1000);
|
||||||
window.setInterval(this.refresh, 5 * 60 * 1000);
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
function refresh() {
|
||||||
this.toolFilter = urlParams.get('tool');
|
if (calendar_ref.value !== null) {
|
||||||
}
|
const calendar = calendar_ref.value.getApi() as Calendar;
|
||||||
|
|
||||||
refresh() {
|
|
||||||
const calendarComponent = this.$refs.calendar as InstanceType<
|
|
||||||
typeof FullCalendar
|
|
||||||
>;
|
|
||||||
const calendar = calendarComponent.getApi() as Calendar;
|
|
||||||
calendar.refetchEvents();
|
calendar.refetchEvents();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eventDataTransform(eventData: EventInput): EventInput | false {
|
function eventDataTransform(eventData: EventInput): EventInput | false {
|
||||||
// clear the url to prevent clicking on the event
|
// clear the url to prevent clicking on the event
|
||||||
delete eventData.url;
|
delete eventData.url;
|
||||||
|
|
||||||
const match = eventData?.title?.match(/([^\/]*) \| ([^-]*) - (.*)/);
|
const match = eventData?.title?.match(/([^\/]*) \| ([^-]*) - (.*)/);
|
||||||
if (match) {
|
if (match) {
|
||||||
const [, member, shop, tool] = match;
|
const [, member, shop, tool] = match;
|
||||||
eventData.title = `${tool} - ${member}`;
|
eventData.title = `${tool} - ${member}`;
|
||||||
if (this.toolFilter === null || tool.includes(this.toolFilter)) {
|
if (toolFilter === null || tool.includes(toolFilter)) {
|
||||||
return eventData;
|
return eventData;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
<body>
|
|
||||||
<div id="app"></div>
|
|
||||||
<script src="index.ts"></script>
|
|
||||||
</body>
|
|
17
src/index.ts
17
src/index.ts
@ -1,18 +1,7 @@
|
|||||||
import 'core-js/modules/es.object.entries';
|
import 'core-js/modules/es.object.entries';
|
||||||
|
|
||||||
// TODO: could probably be a dynamic import
|
import * as Vue from 'vue';
|
||||||
import intl from 'intl';
|
|
||||||
import 'intl/locale-data/jsonp/en.js';
|
|
||||||
|
|
||||||
if (!window.Intl) {
|
import App from './App.vue';
|
||||||
// No `Intl`, so use and load the polyfill.
|
|
||||||
window.Intl = intl;
|
|
||||||
}
|
|
||||||
|
|
||||||
import Vue from 'vue';
|
const app = Vue.createApp(App).mount('#app');
|
||||||
|
|
||||||
import App from './App';
|
|
||||||
|
|
||||||
let app = new Vue({
|
|
||||||
render: (h) => h(App),
|
|
||||||
}).$mount('#app');
|
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "esnext",
|
||||||
"strict": true,
|
"useDefineForClassFields": true,
|
||||||
"module": "es2015",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"resolveJsonModule": true
|
"strict": true,
|
||||||
}
|
"jsx": "preserve",
|
||||||
|
"sourceMap": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": ["esnext", "dom"]
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
}
|
}
|
||||||
|
13
vite.config.ts
Normal file
13
vite.config.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import vue from '@vitejs/plugin-vue';
|
||||||
|
import legacy from '@vitejs/plugin-legacy'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
legacy({
|
||||||
|
targets: ['defaults', 'not IE 11', "ios 8.4"]
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user