Skip to content
Snippets Groups Projects
Verified Commit 0fcba810 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Fix and simplify integration of custom detail dialogs and event bars for calendar events

parent b2064181
No related branches found
No related tags found
1 merge request!1148Calendar events and iCal feeds
Showing
with 153 additions and 83 deletions
<template>
<v-menu
v-model="model"
:close-on-content-click="false"
:activator="selectedElement"
offset-x
>
<v-card min-width="350px" flat>
<v-toolbar :color="selectedEvent.color" dark dense>
<v-toolbar-title>
<slot name="title" :selected-event="selectedEvent">{{
selectedEvent.name
}}</slot>
</v-toolbar-title>
<v-spacer></v-spacer>
<slot name="badge" :selected-event="selectedEvent">
<v-chip
v-if="selectedEvent.status === 'CANCELLED' && !withoutBadge"
color="error"
label
>
<v-avatar left>
<v-icon>mdi-cancel</v-icon>
</v-avatar>
{{ $t("calendar.cancelled") }}
</v-chip>
</slot>
</v-toolbar>
<slot name="time" :selected-event="selectedEvent">
<v-card-text v-if="!withoutTime">
<v-icon left>mdi-calendar-today-outline</v-icon>
<span v-if="selectedEvent.start !== selectedEvent.end">
{{ $d(selectedEvent.start, "shortDateTime") }}
{{ $d(selectedEvent.end, "shortDateTime") }}
</span>
<span v-else> {{ $d(selectedEvent.start, "shortDateTime") }}</span>
</v-card-text>
</slot>
<slot name="description" :selected-event="selectedEvent">
<v-divider v-if="selectedEvent.description && !withoutDescription" />
<v-card-text
class="d-flex"
v-if="selectedEvent.description && !withoutDescription"
>
<div>
<v-icon left>mdi-card-text-outline</v-icon>
</div>
<div style="white-space: pre-line">
{{ selectedEvent.description }}
</div>
</v-card-text>
</slot>
</v-card>
</v-menu>
</template>
<script>
import calendarFeedDetailsMixin from "../../mixins/calendarFeedDetails.js";
export default {
name: "BaseCalendarFeedDetails",
mixins: [calendarFeedDetailsMixin],
};
</script>
<template>
<div
class="mx-1 text-truncate"
:style="
event.status === 'CANCELLED' ? 'text-decoration: line-through;' : ''
"
>
<slot name="time" v-bind="$props">
<span
v-if="
calendarType === 'month' && eventParsed.start.hasTime && !withoutTime
"
class="mr-1 font-weight-bold"
>{{ eventParsed.start.time }}</span
>
</slot>
<slot name="icon" v-bind="$props">
<v-icon v-if="icon" x-small color="white" class="mx-1 left">
{{ icon }}
</v-icon>
</slot>
<slot name="title" v-bind="$props">
{{ event.name }}
</slot>
</div>
</template>
<script>
import calendarFeedEventBarMixin from "../../mixins/calendarFeedEventBar.js";
export default {
name: "BaseCalendarFeedEventBar",
mixins: [calendarFeedEventBarMixin],
};
</script>
......@@ -107,16 +107,16 @@
>
<template #event="{ event, eventParsed, timed }">
<component
:is="eventBarComponentForFeed(event.category)"
:is="eventBarComponentForFeed(event.calendarFeedName)"
:event="event"
:event-parsed="eventParsed"
:calendarType="currentCalendarType"
:calendar-type="currentCalendarType"
/>
</template>
</v-calendar>
<component
v-if="calendarFeeds && selectedEvent"
:is="detailComponentForFeed(selectedEvent.category)"
:is="detailComponentForFeed(selectedEvent.calendarFeedName)"
v-model="selectedOpen"
:selected-element="selectedElement"
:selected-event="selectedEvent"
......@@ -190,6 +190,7 @@ export default {
cf.feed.events.map((event) => ({
...event,
category: cf.verboseName,
calendarFeedName: cf.name,
start: new Date(event.start),
end: new Date(event.end),
color: event.color ? event.color : cf.color,
......@@ -228,9 +229,9 @@ export default {
if (
this.calendarFeeds &&
feedName &&
Object.keys(calendarFeedDetailComponents).includes(feedName + "Details")
Object.keys(calendarFeedDetailComponents).includes(feedName + "details")
) {
return calendarFeedDetailComponents[feedName + "Details"];
return calendarFeedDetailComponents[feedName + "details"];
}
return GenericCalendarFeedDetails;
},
......@@ -239,10 +240,10 @@ export default {
this.calendarFeeds &&
feedName &&
Object.keys(calendarFeedEventBarComponents).includes(
feedName + "EventBar"
feedName + "eventbar"
)
) {
return calendarFeedEventBarComponents[feedName + "EventBar"];
return calendarFeedEventBarComponents[feedName + "eventbar"];
}
return GenericCalendarFeedEventBar;
},
......
<template>
<v-menu
v-model="model"
:close-on-content-click="false"
:activator="selectedElement"
offset-x
>
<v-card min-width="350px" flat>
<v-toolbar :color="selectedEvent.color" dark dense>
<v-toolbar-title>{{ selectedEvent.name }}</v-toolbar-title>
<v-spacer></v-spacer>
<v-chip v-if="selectedEvent.status === 'CANCELLED'" color="error" label>
<v-avatar left>
<v-icon>mdi-cancel</v-icon>
</v-avatar>
{{ $t("calendar.cancelled") }}
</v-chip>
</v-toolbar>
<v-card-text>
<v-icon left>mdi-calendar-today-outline</v-icon>
<span v-if="selectedEvent.start !== selectedEvent.end">
{{ $d(selectedEvent.start, "shortDateTime") }}
{{ $d(selectedEvent.end, "shortDateTime") }}
</span>
<span v-else> {{ $d(selectedEvent.start, "shortDateTime") }}</span>
</v-card-text>
<v-divider v-if="selectedEvent.description" />
<v-card-text class="d-flex" v-if="selectedEvent.description">
<div>
<v-icon left>mdi-card-text-outline</v-icon>
</div>
<div style="white-space: pre-line">
{{ selectedEvent.description }}
</div>
</v-card-text>
</v-card>
</v-menu>
<base-calendar-feed-details v-bind="$props" />
</template>
<script>
import calendarFeedDetailsMixin from "../../mixins/calendarFeedDetails.js";
import BaseCalendarFeedDetails from "./BaseCalendarFeedDetails.vue";
export default {
name: "GenericCalendarFeedDetails",
components: { BaseCalendarFeedDetails },
mixins: [calendarFeedDetailsMixin],
};
</script>
<template>
<div
class="mx-1 truncate"
:style="
event.status === 'CANCELLED' ? 'text-decoration: line-through;' : ''
"
>
<span
v-if="calendarType === 'month' && eventParsed.start.hasTime"
class="mr-1 font-weight-bold"
>{{ eventParsed.start.time }}</span
>
{{ event.name }}
</div>
<base-calendar-feed-event-bar v-bind="$props" />
</template>
<script>
import calendarFeedEventBarMixin from "../../mixins/calendarFeedEventBar.js";
import BaseCalendarFeedEventBar from "./BaseCalendarFeedEventBar.vue";
export default {
name: "GenericCalendarFeedEventBar",
components: { BaseCalendarFeedEventBar },
mixins: [calendarFeedEventBarMixin],
};
</script>
<template>
<v-menu
v-model="model"
:close-on-content-click="false"
:activator="selectedElement"
offset-x
>
<v-card color="grey lighten-4" min-width="350px" flat>
<v-toolbar :color="selectedEvent.color" dark>
<v-toolbar-title>{{ selectedEvent.name }}</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon @click="model = false">
<v-icon>mdi-close</v-icon>
</v-btn>
</v-toolbar>
<base-calendar-feed-details v-bind="$props" without-time>
<template #description="{ selectedEvent }">
<v-divider />
<v-card-text>
<span>
<v-icon class="mr-2">mdi-cake-variant-outline</v-icon>
{{ $d(selectedEvent.start) }}
</span>
</v-card-text>
</v-card>
</v-menu>
</template>
</base-calendar-feed-details>
</template>
<script>
import calendarFeedDetailsMixin from "../../../mixins/calendarFeedDetails.js";
import BaseCalendarFeedDetails from "../../calendar/BaseCalendarFeedDetails.vue";
export default {
name: "BirthdaysDetails",
components: { BaseCalendarFeedDetails },
mixins: [calendarFeedDetailsMixin],
};
</script>
<template>
<v-row align="center">
<v-col cols="2">
<v-icon x-small color="white" class="ml-2"
>mdi-cake-variant-outline</v-icon
>
</v-col>
<v-col cols="10" class="text-truncate">
{{ event.name }}
</v-col>
</v-row>
<base-calendar-feed-event-bar
v-bind="$props"
icon="mdi-cake-variant-outline"
/>
</template>
<script>
import calendarFeedEventBarMixin from "../../../mixins/calendarFeedEventBar.js";
import BaseCalendarFeedEventBar from "../../calendar/BaseCalendarFeedEventBar.vue";
export default {
name: "BirthdaysEventBar",
components: { BaseCalendarFeedEventBar },
mixins: [calendarFeedEventBarMixin],
};
</script>
......@@ -12,6 +12,21 @@ const calendarFeedDetailsMixin = {
type: Object,
},
value: { type: Boolean, required: true },
withoutTime: {
required: true,
type: Boolean,
default: false,
},
withoutDescription: {
required: true,
type: Boolean,
default: false,
},
withoutBadge: {
required: true,
type: Boolean,
default: false,
},
},
computed: {
model: {
......
......@@ -15,6 +15,16 @@ const calendarFeedEventBarMixin = {
required: true,
type: String,
},
icon: {
required: false,
type: String,
default: "",
},
withoutTime: {
required: true,
type: Boolean,
default: false,
},
},
};
......
......@@ -76,7 +76,7 @@ function generateComponentsImportCode(
for (file of files) {
let componentName = file.split(".")[0];
code += `import ${componentName} from '${componentsPath + file}';\n`;
code += `${exportName}["${componentName}"] = ${componentName};\n`;
code += `${exportName}["${componentName.toLowerCase()}"] = ${componentName};\n`;
}
}
return code;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment