mirror of
https://github.com/nottinghamtec/PyRIGS.git
synced 2026-02-20 13:29:41 +00:00
Initial work at reimplementing the calendar in python
Buhby fullcalendar
This commit is contained in:
@@ -401,6 +401,12 @@ class BaseEvent(models.Model, RevisionMixin):
|
|||||||
errdict['end_time'] = ['Unless you\'ve invented time travel, the event can\'t finish before it has started.']
|
errdict['end_time'] = ['Unless you\'ve invented time travel, the event can\'t finish before it has started.']
|
||||||
return errdict
|
return errdict
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_html_url(self):
|
||||||
|
return f'<a href="{self.get_edit_url()}"><span class="badge badge-{self.color}">{self}</span></a>'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"{self.display_id}: {self.name}"
|
||||||
|
|
||||||
@reversion.register(follow=['items'])
|
@reversion.register(follow=['items'])
|
||||||
class Event(BaseEvent):
|
class Event(BaseEvent):
|
||||||
@@ -502,13 +508,29 @@ class Event(BaseEvent):
|
|||||||
else:
|
else:
|
||||||
return bool(self.purchase_order)
|
return bool(self.purchase_order)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color(self):
|
||||||
|
if self.cancelled:
|
||||||
|
return "secondary"
|
||||||
|
elif not self.is_rig:
|
||||||
|
return "info"
|
||||||
|
elif not self.mic:
|
||||||
|
return "danger"
|
||||||
|
elif self.confirmed and self.authorised:
|
||||||
|
if self.dry_hire or self.riskassessment:
|
||||||
|
return "success"
|
||||||
|
else:
|
||||||
|
return "warning"
|
||||||
|
else:
|
||||||
|
return "warning"
|
||||||
|
|
||||||
objects = EventManager()
|
objects = EventManager()
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('event_detail', kwargs={'pk': self.pk})
|
return reverse('event_detail', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
def __str__(self):
|
def get_edit_url(self):
|
||||||
return f"{self.display_id}: {self.name}"
|
return reverse('event_update', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
errdict = super.clean()
|
errdict = super.clean()
|
||||||
@@ -581,6 +603,13 @@ class Subhire(BaseEvent):
|
|||||||
def display_id(self):
|
def display_id(self):
|
||||||
return f"S{self.pk:05d}"
|
return f"S{self.pk:05d}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color(self):
|
||||||
|
return "purple"
|
||||||
|
|
||||||
|
def get_edit_url(self):
|
||||||
|
return reverse('subhire_update', kwargs={'pk': self.pk})
|
||||||
|
|
||||||
|
|
||||||
class InvoiceManager(models.Manager):
|
class InvoiceManager(models.Manager):
|
||||||
def outstanding_invoices(self):
|
def outstanding_invoices(self):
|
||||||
|
|||||||
@@ -4,194 +4,56 @@
|
|||||||
{% block title %}Calendar{% endblock %}
|
{% block title %}Calendar{% endblock %}
|
||||||
|
|
||||||
{% block css %}
|
{% block css %}
|
||||||
<link href="{% static 'css/main.css' %}" rel='stylesheet' />
|
<style>
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block js %}
|
.calendar {
|
||||||
<script src="{% static 'js/moment.js' %}"></script>
|
width: 98%;
|
||||||
<script src="{% static 'js/main.js' %}"></script>
|
margin: auto;
|
||||||
<script>
|
font-size: 13px;
|
||||||
viewToUrl = {
|
}
|
||||||
'timeGridWeek':'week',
|
|
||||||
'timeGridDay':'day',
|
|
||||||
'dayGridMonth':'month'
|
|
||||||
}
|
|
||||||
viewFromUrl = {
|
|
||||||
'week':'timeGridWeek',
|
|
||||||
'day':'timeGridDay',
|
|
||||||
'month':'dayGridMonth'
|
|
||||||
}
|
|
||||||
var calendar; //Need to access it from jquery ready
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var calendarEl = document.getElementById('calendar');
|
|
||||||
|
|
||||||
calendar = new FullCalendar.Calendar(calendarEl, {
|
.calendar tr, .calendar td {
|
||||||
themeSystem: 'bootstrap',
|
border: 1px solid black;
|
||||||
aspectRatio: 1.5,
|
}
|
||||||
eventTimeFormat: {
|
|
||||||
'hour': '2-digit',
|
|
||||||
'minute': '2-digit',
|
|
||||||
'hour12': false
|
|
||||||
},
|
|
||||||
headerToolbar: false,
|
|
||||||
editable: false,
|
|
||||||
dayMaxEventRows: true, // allow "more" link when too many events
|
|
||||||
events: function(fetchInfo, successCallback, failureCallback) {
|
|
||||||
$.ajax({
|
|
||||||
url: '/api/event',
|
|
||||||
dataType: 'json',
|
|
||||||
data: {
|
|
||||||
start: moment(fetchInfo.startStr).format("YYYY-MM-DD[T]HH:mm:ss"),
|
|
||||||
end: moment(fetchInfo.endStr).format("YYYY-MM-DD[T]HH:mm:ss")
|
|
||||||
},
|
|
||||||
success: function(doc) {
|
|
||||||
var events = [];
|
|
||||||
colours = {
|
|
||||||
'Provisional': '#FFE89B',
|
|
||||||
'Confirmed': '#3AB54A' ,
|
|
||||||
'Booked': '#3AB54A' ,
|
|
||||||
'Cancelled': 'grey' ,
|
|
||||||
'non-rig': '#25AAE2'
|
|
||||||
};
|
|
||||||
$(doc).each(function() {
|
|
||||||
end = $(this).attr('latest')
|
|
||||||
allDay = false
|
|
||||||
if(end.indexOf("T") < 0){ //If latest does not contain a time
|
|
||||||
end = moment(end + " 23:59").format("YYYY-MM-DD[T]HH:mm:ss")
|
|
||||||
allDay = true
|
|
||||||
}
|
|
||||||
|
|
||||||
thisEvent = {
|
.calendar th {
|
||||||
'start': $(this).attr('earliest'),
|
padding: 10px;
|
||||||
'end': end,
|
text-align: center;
|
||||||
'className': 'modal-href',
|
font-size: 18px;
|
||||||
'title': $(this).attr('title'),
|
}
|
||||||
'url': $(this).attr('url'),
|
|
||||||
'allDay': allDay
|
|
||||||
}
|
|
||||||
|
|
||||||
if($(this).attr('is_rig')===true || $(this).attr('status') === "Cancelled"){
|
.calendar td {
|
||||||
thisEvent['color'] = colours[$(this).attr('status')];
|
width: 200px;
|
||||||
}else{
|
height: 150px;
|
||||||
thisEvent['color'] = colours['non-rig'];
|
padding: 20px 0px 0px 5px;
|
||||||
}
|
}
|
||||||
events.push(thisEvent);
|
|
||||||
});
|
|
||||||
successCallback(events);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
datesSet: function(info) {
|
|
||||||
var view = info.view;
|
|
||||||
// Set the title of the view
|
|
||||||
$('#calendar-header').text(view.title);
|
|
||||||
|
|
||||||
// Enable/Disable "Today" button as required
|
.month {
|
||||||
let $today = $('#today-button');
|
font-size: 25px;
|
||||||
if(moment().isBetween(view.currentStart, view.currentEnd)){
|
}
|
||||||
//Today is within the current view
|
|
||||||
$today.prop('disabled', true);
|
|
||||||
}else{
|
|
||||||
$today.prop('disabled', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set active view select button
|
.date {
|
||||||
let $month = $('#month-button');
|
font-size: 16px;
|
||||||
let $week = $('#week-button');
|
}
|
||||||
let $day = $('#day-button');
|
|
||||||
switch(view.type){
|
|
||||||
case 'dayGridMonth':
|
|
||||||
$month.addClass('active');
|
|
||||||
$week.removeClass('active');
|
|
||||||
$day.removeClass('active');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'timeGridWeek':
|
ul {
|
||||||
$month.removeClass('active');
|
height: 100%;
|
||||||
$week.addClass('active');
|
padding: 0px 5px 0px 20px;
|
||||||
$day.removeClass('active');
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case 'timeGridDay':
|
a {
|
||||||
$month.removeClass('active');
|
color: #17a2b8;
|
||||||
$week.removeClass('active');
|
}
|
||||||
$day.addClass('active');
|
.badge-purple, .bg-purple {
|
||||||
break;
|
background-color: #800080 !important;
|
||||||
}
|
}
|
||||||
history.replaceState(null,null,"{% url 'web_calendar' %}"+viewToUrl[view.type]+'/'+moment(view.currentStart).format('YYYY-MM-DD')+'/');
|
</style>
|
||||||
}
|
|
||||||
});
|
|
||||||
calendar.render();
|
|
||||||
});
|
|
||||||
$(document).ready(function() {
|
|
||||||
// set some button listeners
|
|
||||||
$('#next-button').click(function(){ calendar.next(); });
|
|
||||||
$('#prev-button').click(function(){ calendar.prev(); });
|
|
||||||
$('#today-button').click(function(){ calendar.today(); });
|
|
||||||
$('#month-button').click(function(){ calendar.changeView('dayGridMonth'); });
|
|
||||||
$('#week-button').click(function(){ calendar.changeView('timeGridWeek'); });
|
|
||||||
$('#day-button').click(function(){ calendar.changeView('timeGridDay'); });
|
|
||||||
$('#go-to-date-input').change(function(){
|
|
||||||
if(moment($('#go-to-date-input').val()).isValid()){
|
|
||||||
$('#go-to-date-button').prop('disabled', false);
|
|
||||||
} else{
|
|
||||||
$('#go-to-date-button').prop('disabled', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
$('#go-to-date-button').click(function(){
|
|
||||||
day = moment($('#go-to-date-input').val());
|
|
||||||
if(day.isValid()){
|
|
||||||
calendar.gotoDate(day.format("YYYY-MM-DD"));
|
|
||||||
} else{
|
|
||||||
alert('Invalid Date');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
{% if view and date %}
|
|
||||||
// Go to the initial settings, if they're valid
|
|
||||||
view = viewFromUrl['{{view}}'];
|
|
||||||
calendar.changeView(view);
|
|
||||||
day = moment('{{date}}');
|
|
||||||
if(day.isValid()){
|
|
||||||
calendar.gotoDate(day.format("YYYY-MM-DD"));
|
|
||||||
} else{
|
|
||||||
console.log('Supplied date is invalid - using default')
|
|
||||||
}
|
|
||||||
{% endif %}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row">
|
<div class="clearfix">
|
||||||
<div class="col-sm-12">
|
<a class="btn btn-info left" href="{% url 'web_calendar' %}?{{ prev_month }}"> Previous Month </a>
|
||||||
<div class="pull-left">
|
<a class="btn btn-info right" href="{% url 'web_calendar' %}?{{ next_month }}"> Next Month </a>
|
||||||
<span id="calendar-header" class="h2"></span>
|
</div>
|
||||||
</div>
|
{{ calendar }}
|
||||||
<div class="form-inline float-right btn-page my-3">
|
|
||||||
<div class="input-group mx-2">
|
|
||||||
<input type="date" class="form-control" id="go-to-date-input" placeholder="Go to date...">
|
|
||||||
<span class="input-group-append">
|
|
||||||
<button class="btn btn-success" id="go-to-date-button" type="button" disabled>Go!</button>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="btn-group mx-2">
|
|
||||||
<button type="button" class="btn btn-primary" id="today-button">Today</button>
|
|
||||||
</div>
|
|
||||||
<div class="btn-group mx-2">
|
|
||||||
<button type="button" class="btn btn-secondary" id="prev-button"><span class="fas fa-chevron-left"></span></button>
|
|
||||||
<button type="button" class="btn btn-secondary" id="next-button"><span class="fas fa-chevron-right"></span></button>
|
|
||||||
</div>
|
|
||||||
<div class="btn-group ml-2">
|
|
||||||
<button type="button" class="btn btn-light" id="month-button">Month</button>
|
|
||||||
<button type="button" class="btn btn-light" id="week-button">Week</button>
|
|
||||||
<button type="button" class="btn btn-light" id="day-button">Day</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-12">
|
|
||||||
<div id='calendar'></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -12,21 +12,7 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for event in events %}
|
{% for event in events %}
|
||||||
<tr class="{% if event.cancelled %}
|
<tr class="table-{{event.color}}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
|
||||||
table-secondary
|
|
||||||
{% elif not event.is_rig %}
|
|
||||||
table-info
|
|
||||||
{% elif not event.mic %}
|
|
||||||
table-danger
|
|
||||||
{% elif event.confirmed and event.authorised %}
|
|
||||||
{% if event.dry_hire or event.riskassessment %}
|
|
||||||
table-success
|
|
||||||
{% else %}
|
|
||||||
table-warning
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
table-warning
|
|
||||||
{% endif %}" {% if event.cancelled %}style="opacity: 50% !important;"{% endif %} id="event_row">
|
|
||||||
<!---Number-->
|
<!---Number-->
|
||||||
<th scope="row" id="event_number">{{ event.display_id }}</th>
|
<th scope="row" id="event_number">{{ event.display_id }}</th>
|
||||||
<!--Dates & Times-->
|
<!--Dates & Times-->
|
||||||
|
|||||||
@@ -43,12 +43,8 @@ urlpatterns = [
|
|||||||
|
|
||||||
# Rigboard
|
# Rigboard
|
||||||
path('rigboard/', login_required(views.RigboardIndex.as_view()), name='rigboard'),
|
path('rigboard/', login_required(views.RigboardIndex.as_view()), name='rigboard'),
|
||||||
path('rigboard/calendar/', login_required()(views.WebCalendar.as_view()),
|
re_path(r'^rigboard/calendar/$', login_required()(views.WebCalendar.as_view()),
|
||||||
name='web_calendar'),
|
name='web_calendar'),
|
||||||
re_path(r'^rigboard/calendar/(?P<view>(month|week|day))/$',
|
|
||||||
login_required()(views.WebCalendar.as_view()), name='web_calendar'),
|
|
||||||
re_path(r'^rigboard/calendar/(?P<view>(month|week|day))/(?P<date>(\d{4}-\d{2}-\d{2}))/$',
|
|
||||||
login_required()(views.WebCalendar.as_view()), name='web_calendar'),
|
|
||||||
path('rigboard/archive/', RedirectView.as_view(permanent=True, pattern_name='event_archive')),
|
path('rigboard/archive/', RedirectView.as_view(permanent=True, pattern_name='event_archive')),
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +73,7 @@ urlpatterns = [
|
|||||||
path('subhire/create/', permission_required_with_403('RIGS.add_event')(views.SubhireCreate.as_view()),
|
path('subhire/create/', permission_required_with_403('RIGS.add_event')(views.SubhireCreate.as_view()),
|
||||||
name='subhire_create'),
|
name='subhire_create'),
|
||||||
path('subhire/<int:pk>/edit', views.SubhireEdit.as_view(),
|
path('subhire/<int:pk>/edit', views.SubhireEdit.as_view(),
|
||||||
name='subhire_edit'),
|
name='subhire_update'),
|
||||||
|
|
||||||
|
|
||||||
# Event H&S
|
# Event H&S
|
||||||
|
|||||||
65
RIGS/utils.py
Normal file
65
RIGS/utils.py
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
from datetime import datetime, timedelta, date
|
||||||
|
import calendar
|
||||||
|
from calendar import HTMLCalendar
|
||||||
|
from RIGS.models import BaseEvent, Event, Subhire
|
||||||
|
|
||||||
|
class Calendar(HTMLCalendar):
|
||||||
|
def __init__(self, year=None, month=None):
|
||||||
|
self.year = year
|
||||||
|
self.month = month
|
||||||
|
super(Calendar, self).__init__()
|
||||||
|
|
||||||
|
# formats a day as a td
|
||||||
|
# filter events by day
|
||||||
|
def formatday(self, day, events, subhires):
|
||||||
|
events_per_day = events.filter(start_date__day=day)
|
||||||
|
subhires_per_day = subhires.filter(start_date__day=day)
|
||||||
|
d = ''
|
||||||
|
for event in events_per_day:
|
||||||
|
d += f'{event.get_html_url}<br>'
|
||||||
|
for subhire in subhires_per_day:
|
||||||
|
d += f'{subhire.get_html_url}<br>'
|
||||||
|
|
||||||
|
if day != 0:
|
||||||
|
return f"<td><span class='date'>{day}</span><ul> {d} </ul></td>"
|
||||||
|
return '<td></td>'
|
||||||
|
|
||||||
|
# formats a week as a tr
|
||||||
|
def formatweek(self, theweek, events, subhires):
|
||||||
|
week = ''
|
||||||
|
for d, weekday in theweek:
|
||||||
|
week += self.formatday(d, events, subhires)
|
||||||
|
return f'<tr> {week} </tr>'
|
||||||
|
|
||||||
|
# formats a month as a table
|
||||||
|
# filter events by year and month
|
||||||
|
def formatmonth(self, withyear=True):
|
||||||
|
events = Event.objects.filter(start_date__year=self.year, start_date__month=self.month)
|
||||||
|
subhires = Subhire.objects.filter(start_date__year=self.year, start_date__month=self.month)
|
||||||
|
|
||||||
|
cal = f'<table border="0" cellpadding="0" cellspacing="0" class="calendar">\n'
|
||||||
|
cal += f'{self.formatmonthname(self.year, self.month, withyear=withyear)}\n'
|
||||||
|
cal += f'{self.formatweekheader()}\n'
|
||||||
|
for week in self.monthdays2calendar(self.year, self.month):
|
||||||
|
cal += f'{self.formatweek(week, events, subhires)}\n'
|
||||||
|
return cal
|
||||||
|
|
||||||
|
|
||||||
|
def get_date(req_day):
|
||||||
|
if req_day:
|
||||||
|
year, month = (int(x) for x in req_day.split('-'))
|
||||||
|
return date(year, month, day=1)
|
||||||
|
return datetime.today()
|
||||||
|
|
||||||
|
def prev_month(d):
|
||||||
|
first = d.replace(day=1)
|
||||||
|
prev_month = first - timedelta(days=1)
|
||||||
|
month = 'month=' + str(prev_month.year) + '-' + str(prev_month.month)
|
||||||
|
return month
|
||||||
|
|
||||||
|
def next_month(d):
|
||||||
|
days_in_month = calendar.monthrange(d.year, d.month)[1]
|
||||||
|
last = d.replace(day=days_in_month)
|
||||||
|
next_month = last + timedelta(days=1)
|
||||||
|
month = 'month=' + str(next_month.year) + '-' + str(next_month.month)
|
||||||
|
return month
|
||||||
@@ -17,12 +17,13 @@ from django.template.loader import get_template
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.html import mark_safe
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
|
|
||||||
from PyRIGS import decorators
|
from PyRIGS import decorators
|
||||||
from PyRIGS.views import OEmbedView, is_ajax, ModalURLMixin, PrintView, get_related
|
from PyRIGS.views import OEmbedView, is_ajax, ModalURLMixin, PrintView, get_related
|
||||||
from RIGS import models, forms
|
from RIGS import models, forms, utils
|
||||||
|
|
||||||
__author__ = 'ghost'
|
__author__ = 'ghost'
|
||||||
|
|
||||||
@@ -40,14 +41,24 @@ class RigboardIndex(generic.TemplateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class WebCalendar(generic.TemplateView):
|
class WebCalendar(generic.ListView):
|
||||||
|
model = models.Event
|
||||||
template_name = 'calendar.html'
|
template_name = 'calendar.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
context['view'] = kwargs.get('view', '')
|
|
||||||
context['date'] = kwargs.get('date', '')
|
# use today's date for the calendar
|
||||||
# context['page_title'] = "Calendar"
|
d = utils.get_date(self.request.GET.get('month', None))
|
||||||
|
context['prev_month'] = utils.prev_month(d)
|
||||||
|
context['next_month'] = utils.next_month(d)
|
||||||
|
|
||||||
|
# Instantiate our calendar class with today's year and date
|
||||||
|
cal = utils.Calendar(d.year, d.month)
|
||||||
|
|
||||||
|
# Call the formatmonth method, which returns our calendar as a table
|
||||||
|
html_cal = cal.formatmonth(withyear=True)
|
||||||
|
context['calendar'] = mark_safe(html_cal)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -5,7 +5,6 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "PyRIGS",
|
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "Custom",
|
"license": "Custom",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -19,7 +18,6 @@
|
|||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.8",
|
||||||
"cssnano": "^5.0.13",
|
"cssnano": "^5.0.13",
|
||||||
"easymde": "^2.16.1",
|
"easymde": "^2.16.1",
|
||||||
"fullcalendar": "^5.10.1",
|
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-flatten": "^0.4.0",
|
"gulp-flatten": "^0.4.0",
|
||||||
@@ -2943,11 +2941,6 @@
|
|||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fullcalendar": {
|
|
||||||
"version": "5.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-5.10.1.tgz",
|
|
||||||
"integrity": "sha512-0jgDxiWRuC36MzAUK3+Equmu4R0+vAPEtttsXLX9GNNDUHEZ5HjcH+dUtWut4vlJtxGJgVZ+eZ76/7qhcu+RMA=="
|
|
||||||
},
|
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
@@ -11350,11 +11343,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"fullcalendar": {
|
|
||||||
"version": "5.10.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-5.10.1.tgz",
|
|
||||||
"integrity": "sha512-0jgDxiWRuC36MzAUK3+Equmu4R0+vAPEtttsXLX9GNNDUHEZ5HjcH+dUtWut4vlJtxGJgVZ+eZ76/7qhcu+RMA=="
|
|
||||||
},
|
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
"clipboard": "^2.0.8",
|
"clipboard": "^2.0.8",
|
||||||
"cssnano": "^5.0.13",
|
"cssnano": "^5.0.13",
|
||||||
"easymde": "^2.16.1",
|
"easymde": "^2.16.1",
|
||||||
"fullcalendar": "^5.10.1",
|
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-concat": "^2.6.1",
|
"gulp-concat": "^2.6.1",
|
||||||
"gulp-flatten": "^0.4.0",
|
"gulp-flatten": "^0.4.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user