Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature full calendar component #26

Merged
merged 7 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addon/components/full-calendar.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div id="fleetbase-full-calendar" class="fleetbase-full-calendar" {{did-insert this.setupCalendar}}></div>
110 changes: 110 additions & 0 deletions addon/components/full-calendar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { classify } from '@ember/string';
import { Calendar } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import interactionPlugin from '@fullcalendar/interaction';

export default class FullCalendarComponent extends Component {
/**
* @var {HTMLElement} calendarEl
*/
@tracked calendarEl;

/**
* @var {Calendar} calendar
* @package @fullcalendar/core
*/
@tracked calendar;

/**
* Default events to trigger for
* @var {Array}
*/
@tracked events = ['dateClick', 'drop', 'eventReceive', 'eventClick', 'eventDragStop', 'eventDrop', 'eventAdd', 'eventChange', 'eventRemove'];

/**
* Tracked calendar event listeners
* @var {Array}
*/
@tracked _listeners = [];

/**
* Initializes and renders the calendar component
*
* @param {HTMLElement} calendarEl
*/
@action setupCalendar(calendarEl) {
// track calendar htmlelement
this.calendarEl = calendarEl;

// get events
let events = this.args.events || [];

// initialize calendar
this.calendar = new Calendar(calendarEl, {
events,
plugins: [dayGridPlugin, interactionPlugin],
initialView: 'dayGridMonth',
editable: true,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: '',
},
});

// trigger callback on initialize
if (typeof this.args.onInit === 'function') {
this.args.onInit(this.calendar);
}

// render calendar
this.calendar.render();

// listen for events
this.createCalendarEventListeners();
}

triggerCalendarEvent(eventName, ...params) {
if (typeof this[eventName] === 'function') {
this[eventName](...params);
}

if (typeof this.args[eventName] === 'function') {
this.args[eventName](...params);
}
}

createCalendarEventListeners() {
for (let i = 0; i < this.events.length; i++) {
const eventName = this.events.objectAt(i);
const callbackName = `on${classify(eventName)}`;

if (typeof this.args[callbackName] === 'function') {
// track for destroy purposes
this._listeners.pushObject({
eventName,
callbackName,
});

// create listener
this.calendar.on(eventName, this.triggerCalendarEvent.bind(this, callbackName));
}
}

// check for custom events
// @todo
}

destroyCalendarEventListeners() {
for (let i = 0; i < this._listeners.length; i++) {
const listener = this._listeners.objectAt(i);
const { eventName, callbackName } = listener;

// kill listener
this.calendar.off(eventName, this.triggerCalendarEvent.bind(this, callbackName));
}
}
}
3 changes: 3 additions & 0 deletions addon/components/full-calendar/draggable.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="fleetbase-full-calendar-draggable" data-event={{@eventData}} {{did-insert this.makeDraggable}} ...attributes>
{{yield}}
</div>
18 changes: 18 additions & 0 deletions addon/components/full-calendar/draggable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { Draggable } from '@fullcalendar/interaction';

export default class DraggableFullcalendarEventComponent extends Component {
@tracked draggable;
@tracked eventData = {};

constructor() {
super(...arguments);
this.eventData = this.args.eventData ?? {};
}

@action makeDraggable(element) {
this.draggable = new Draggable(element);
}
}
5 changes: 3 additions & 2 deletions addon/helpers/json-hash.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { helper } from '@ember/component/helper';

export default helper(function jsonHash(positional /*, named*/) {
return positional;
export default helper(function jsonHash(positional, named) {
let json = JSON.stringify(named);
return json;
});
1 change: 1 addition & 0 deletions addon/styles/addon.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
@import 'components/kanban.css';
@import 'components/notification-tray.css';
@import 'components/fleet-listing.css';
@import 'components/full-calendar.css';

/** Third party */
@import 'air-datepicker/air-datepicker.css';
99 changes: 99 additions & 0 deletions addon/styles/components/full-calendar.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
.fleetbase-full-calendar .fc-toolbar-title {
@apply text-base text-gray-900 font-semibold;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-toolbar-title {
@apply text-gray-200;
}

.fleetbase-full-calendar.fc td,
.fleetbase-full-calendar.fc th {
@apply border-gray-200;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc td,
body[data-theme='dark'] .fleetbase-full-calendar.fc th {
@apply border-gray-700;
}

.fleetbase-full-calendar.fc table.fc-scrollgrid {
@apply border-gray-200;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc table.fc-scrollgrid {
@apply border-gray-700;
}

.fleetbase-full-calendar.fc .fc-button {
@apply inline-flex items-center px-3 py-2 text-sm font-medium leading-4 transition duration-150 ease-in-out border border-transparent rounded-md text-gray-800;
cursor: default !important;
}

.fleetbase-full-calendar.fc .fc-button:disabled,
.fleetbase-full-calendar.fc .fc-button-primary:disabled,
body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:disabled {
@apply opacity-50 cursor-not-allowed;
}

.fleetbase-full-calendar.fc .fc-button .fc-icon {
font-size: 1rem;
}

.fleetbase-full-calendar.fc .fc-toolbar {
justify-content: start;
}

.fleetbase-full-calendar.fc .fc-toolbar.fc-header-toolbar {
margin-bottom: 1rem;
}

.fleetbase-full-calendar.fc .fc-toolbar > .fc-toolbar-chunk {
margin-right: 1.25rem;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary {
@apply text-gray-300 bg-gray-700 border-gray-900 shadow;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:hover:not(:disabled) {
@apply text-gray-200 bg-gray-600;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:focus {
@apply outline-0;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:active:not(:disabled) {
@apply text-gray-300 bg-gray-600;
}

body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button .fc-icon {
@apply text-gray-300;
}

.fleetbase-full-calendar.fc .fc-button-primary {
@apply bg-white border-gray-300 shadow-sm text-gray-800;
}

.fleetbase-full-calendar.fc .fc-button-primary:hover:not(:disabled) {
@apply text-gray-500
}

.fleetbase-full-calendar.fc .fc-button-primary:focus {
@apply border-gray-300 outline-0;
}

.fleetbase-full-calendar.fc .fc-button-primary:active:not(:disabled) {
@apply text-gray-800 bg-gray-50;
}

.fleetbase-full-calendar.fc .fc-button .fc-icon {
@apply text-gray-900;
}

.fleetbase-full-calendar.fc .fc-button-primary:not(:disabled).fc-button-active:focus,
.fleetbase-full-calendar.fc .fc-button-primary:not(:disabled):active:focus,
body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:not(:disabled).fc-button-active:focus,
body[data-theme='dark'] .fleetbase-full-calendar.fc .fc-button-primary:not(:disabled):active:focus {
box-shadow: none;
}
1 change: 1 addition & 0 deletions app/components/full-calendar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/ember-ui/components/full-calendar';
1 change: 1 addition & 0 deletions app/components/full-calendar/draggable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/ember-ui/components/full-calendar/draggable';
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,14 @@
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-brands-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fullcalendar/core": "^6.1.9",
"@fullcalendar/daygrid": "^6.1.9",
"@fullcalendar/interaction": "^6.1.9",
"@makepanic/ember-power-calendar-date-fns": "^0.4.2",
"@tailwindcss/forms": "^0.5.3",
"air-datepicker": "^3.3.5",
"autonumeric": "^4.6.2",
"autoprefixer": "^10.4.15",
"broccoli-funnel": "^3.0.8",
"broccoli-merge-trees": "^4.2.0",
"chart.js": "^4.2.1",
Expand Down Expand Up @@ -80,15 +85,13 @@
"ember-wormhole": "^0.6.0",
"imask": "^6.4.3",
"intl-tel-input": "^18.1.3",
"autoprefixer": "^10.4.15",
"postcss-at-rules-variables": "^0.3.0",
"postcss-conditionals-renewed": "^1.0.0",
"postcss-each": "^1.1.0",
"postcss-import": "^15.1.0",
"postcss-mixins": "^9.0.4",
"postcss-preset-env": "^9.1.1",
"tailwindcss": "^3.1.8",
"@tailwindcss/forms": "^0.5.3"
"tailwindcss": "^3.1.8"
},
"devDependencies": {
"@ember/optional-features": "^2.0.0",
Expand Down
Loading
Loading