Merge branch 'master' into 423-uneingeloste-einladungen-garbage-collecten
This commit is contained in:
commit
28df184748
3
.babelrc
3
.babelrc
@ -4,6 +4,7 @@
|
||||
],
|
||||
"plugins": [
|
||||
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
||||
["@babel/plugin-proposal-class-properties", { "loose": true }]
|
||||
["@babel/plugin-proposal-class-properties", { "loose": true }],
|
||||
["@babel/transform-runtime"]
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,466 +0,0 @@
|
||||
(function(self) {
|
||||
'use strict';
|
||||
|
||||
if (self.fetch) {
|
||||
return
|
||||
}
|
||||
|
||||
var support = {
|
||||
searchParams: 'URLSearchParams' in self,
|
||||
iterable: 'Symbol' in self && 'iterator' in Symbol,
|
||||
blob: 'FileReader' in self && 'Blob' in self && (function() {
|
||||
try {
|
||||
new Blob()
|
||||
return true
|
||||
} catch(e) {
|
||||
return false
|
||||
}
|
||||
})(),
|
||||
formData: 'FormData' in self,
|
||||
arrayBuffer: 'ArrayBuffer' in self
|
||||
}
|
||||
|
||||
if (support.arrayBuffer) {
|
||||
var viewClasses = [
|
||||
'[object Int8Array]',
|
||||
'[object Uint8Array]',
|
||||
'[object Uint8ClampedArray]',
|
||||
'[object Int16Array]',
|
||||
'[object Uint16Array]',
|
||||
'[object Int32Array]',
|
||||
'[object Uint32Array]',
|
||||
'[object Float32Array]',
|
||||
'[object Float64Array]'
|
||||
]
|
||||
|
||||
var isDataView = function(obj) {
|
||||
return obj && DataView.prototype.isPrototypeOf(obj)
|
||||
}
|
||||
|
||||
var isArrayBufferView = ArrayBuffer.isView || function(obj) {
|
||||
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeName(name) {
|
||||
if (typeof name !== 'string') {
|
||||
name = String(name)
|
||||
}
|
||||
if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) {
|
||||
throw new TypeError('Invalid character in header field name')
|
||||
}
|
||||
return name.toLowerCase()
|
||||
}
|
||||
|
||||
function normalizeValue(value) {
|
||||
if (typeof value !== 'string') {
|
||||
value = String(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// Build a destructive iterator for the value list
|
||||
function iteratorFor(items) {
|
||||
var iterator = {
|
||||
next: function() {
|
||||
var value = items.shift()
|
||||
return {done: value === undefined, value: value}
|
||||
}
|
||||
}
|
||||
|
||||
if (support.iterable) {
|
||||
iterator[Symbol.iterator] = function() {
|
||||
return iterator
|
||||
}
|
||||
}
|
||||
|
||||
return iterator
|
||||
}
|
||||
|
||||
function Headers(headers) {
|
||||
this.map = {}
|
||||
|
||||
if (headers instanceof Headers) {
|
||||
headers.forEach(function(value, name) {
|
||||
this.append(name, value)
|
||||
}, this)
|
||||
} else if (Array.isArray(headers)) {
|
||||
headers.forEach(function(header) {
|
||||
this.append(header[0], header[1])
|
||||
}, this)
|
||||
} else if (headers) {
|
||||
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
||||
this.append(name, headers[name])
|
||||
}, this)
|
||||
}
|
||||
}
|
||||
|
||||
Headers.prototype.append = function(name, value) {
|
||||
name = normalizeName(name)
|
||||
value = normalizeValue(value)
|
||||
var oldValue = this.map[name]
|
||||
this.map[name] = oldValue ? oldValue+','+value : value
|
||||
}
|
||||
|
||||
Headers.prototype['delete'] = function(name) {
|
||||
delete this.map[normalizeName(name)]
|
||||
}
|
||||
|
||||
Headers.prototype.get = function(name) {
|
||||
name = normalizeName(name)
|
||||
return this.has(name) ? this.map[name] : null
|
||||
}
|
||||
|
||||
Headers.prototype.has = function(name) {
|
||||
return this.map.hasOwnProperty(normalizeName(name))
|
||||
}
|
||||
|
||||
Headers.prototype.set = function(name, value) {
|
||||
this.map[normalizeName(name)] = normalizeValue(value)
|
||||
}
|
||||
|
||||
Headers.prototype.forEach = function(callback, thisArg) {
|
||||
for (var name in this.map) {
|
||||
if (this.map.hasOwnProperty(name)) {
|
||||
callback.call(thisArg, this.map[name], name, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Headers.prototype.keys = function() {
|
||||
var items = []
|
||||
this.forEach(function(value, name) { items.push(name) })
|
||||
return iteratorFor(items)
|
||||
}
|
||||
|
||||
Headers.prototype.values = function() {
|
||||
var items = []
|
||||
this.forEach(function(value) { items.push(value) })
|
||||
return iteratorFor(items)
|
||||
}
|
||||
|
||||
Headers.prototype.entries = function() {
|
||||
var items = []
|
||||
this.forEach(function(value, name) { items.push([name, value]) })
|
||||
return iteratorFor(items)
|
||||
}
|
||||
|
||||
if (support.iterable) {
|
||||
Headers.prototype[Symbol.iterator] = Headers.prototype.entries
|
||||
}
|
||||
|
||||
function consumed(body) {
|
||||
if (body.bodyUsed) {
|
||||
return Promise.reject(new TypeError('Already read'))
|
||||
}
|
||||
body.bodyUsed = true
|
||||
}
|
||||
|
||||
function fileReaderReady(reader) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
reader.onload = function() {
|
||||
resolve(reader.result)
|
||||
}
|
||||
reader.onerror = function() {
|
||||
reject(reader.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function readBlobAsArrayBuffer(blob) {
|
||||
var reader = new FileReader()
|
||||
var promise = fileReaderReady(reader)
|
||||
reader.readAsArrayBuffer(blob)
|
||||
return promise
|
||||
}
|
||||
|
||||
function readBlobAsText(blob) {
|
||||
var reader = new FileReader()
|
||||
var promise = fileReaderReady(reader)
|
||||
reader.readAsText(blob)
|
||||
return promise
|
||||
}
|
||||
|
||||
function readArrayBufferAsText(buf) {
|
||||
var view = new Uint8Array(buf)
|
||||
var chars = new Array(view.length)
|
||||
|
||||
for (var i = 0; i < view.length; i++) {
|
||||
chars[i] = String.fromCharCode(view[i])
|
||||
}
|
||||
return chars.join('')
|
||||
}
|
||||
|
||||
function bufferClone(buf) {
|
||||
if (buf.slice) {
|
||||
return buf.slice(0)
|
||||
} else {
|
||||
var view = new Uint8Array(buf.byteLength)
|
||||
view.set(new Uint8Array(buf))
|
||||
return view.buffer
|
||||
}
|
||||
}
|
||||
|
||||
function Body() {
|
||||
this.bodyUsed = false
|
||||
|
||||
this._initBody = function(body) {
|
||||
this._bodyInit = body
|
||||
if (!body) {
|
||||
this._bodyText = ''
|
||||
} else if (typeof body === 'string') {
|
||||
this._bodyText = body
|
||||
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
||||
this._bodyBlob = body
|
||||
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
||||
this._bodyFormData = body
|
||||
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
||||
this._bodyText = body.toString()
|
||||
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
||||
this._bodyArrayBuffer = bufferClone(body.buffer)
|
||||
// IE 10-11 can't handle a DataView body.
|
||||
this._bodyInit = new Blob([this._bodyArrayBuffer])
|
||||
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
||||
this._bodyArrayBuffer = bufferClone(body)
|
||||
} else {
|
||||
throw new Error('unsupported BodyInit type')
|
||||
}
|
||||
|
||||
if (!this.headers.get('content-type')) {
|
||||
if (typeof body === 'string') {
|
||||
this.headers.set('content-type', 'text/plain;charset=UTF-8')
|
||||
} else if (this._bodyBlob && this._bodyBlob.type) {
|
||||
this.headers.set('content-type', this._bodyBlob.type)
|
||||
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
||||
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (support.blob) {
|
||||
this.blob = function() {
|
||||
var rejected = consumed(this)
|
||||
if (rejected) {
|
||||
return rejected
|
||||
}
|
||||
|
||||
if (this._bodyBlob) {
|
||||
return Promise.resolve(this._bodyBlob)
|
||||
} else if (this._bodyArrayBuffer) {
|
||||
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
||||
} else if (this._bodyFormData) {
|
||||
throw new Error('could not read FormData body as blob')
|
||||
} else {
|
||||
return Promise.resolve(new Blob([this._bodyText]))
|
||||
}
|
||||
}
|
||||
|
||||
this.arrayBuffer = function() {
|
||||
if (this._bodyArrayBuffer) {
|
||||
return consumed(this) || Promise.resolve(this._bodyArrayBuffer)
|
||||
} else {
|
||||
return this.blob().then(readBlobAsArrayBuffer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.text = function() {
|
||||
var rejected = consumed(this)
|
||||
if (rejected) {
|
||||
return rejected
|
||||
}
|
||||
|
||||
if (this._bodyBlob) {
|
||||
return readBlobAsText(this._bodyBlob)
|
||||
} else if (this._bodyArrayBuffer) {
|
||||
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
||||
} else if (this._bodyFormData) {
|
||||
throw new Error('could not read FormData body as text')
|
||||
} else {
|
||||
return Promise.resolve(this._bodyText)
|
||||
}
|
||||
}
|
||||
|
||||
if (support.formData) {
|
||||
this.formData = function() {
|
||||
return this.text().then(decode)
|
||||
}
|
||||
}
|
||||
|
||||
this.json = function() {
|
||||
return this.text().then(JSON.parse)
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
// HTTP methods whose capitalization should be normalized
|
||||
var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']
|
||||
|
||||
function normalizeMethod(method) {
|
||||
var upcased = method.toUpperCase()
|
||||
return (methods.indexOf(upcased) > -1) ? upcased : method
|
||||
}
|
||||
|
||||
function Request(input, options) {
|
||||
options = options || {}
|
||||
var body = options.body
|
||||
|
||||
if (input instanceof Request) {
|
||||
if (input.bodyUsed) {
|
||||
throw new TypeError('Already read')
|
||||
}
|
||||
this.url = input.url
|
||||
this.credentials = input.credentials
|
||||
if (!options.headers) {
|
||||
this.headers = new Headers(input.headers)
|
||||
}
|
||||
this.method = input.method
|
||||
this.mode = input.mode
|
||||
if (!body && input._bodyInit != null) {
|
||||
body = input._bodyInit
|
||||
input.bodyUsed = true
|
||||
}
|
||||
} else {
|
||||
this.url = String(input)
|
||||
}
|
||||
|
||||
this.credentials = options.credentials || this.credentials || 'omit'
|
||||
if (options.headers || !this.headers) {
|
||||
this.headers = new Headers(options.headers)
|
||||
}
|
||||
this.method = normalizeMethod(options.method || this.method || 'GET')
|
||||
this.mode = options.mode || this.mode || null
|
||||
this.referrer = null
|
||||
|
||||
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
||||
throw new TypeError('Body not allowed for GET or HEAD requests')
|
||||
}
|
||||
this._initBody(body)
|
||||
}
|
||||
|
||||
Request.prototype.clone = function() {
|
||||
return new Request(this, { body: this._bodyInit })
|
||||
}
|
||||
|
||||
function decode(body) {
|
||||
var form = new FormData()
|
||||
body.trim().split('&').forEach(function(bytes) {
|
||||
if (bytes) {
|
||||
var split = bytes.split('=')
|
||||
var name = split.shift().replace(/\+/g, ' ')
|
||||
var value = split.join('=').replace(/\+/g, ' ')
|
||||
form.append(decodeURIComponent(name), decodeURIComponent(value))
|
||||
}
|
||||
})
|
||||
return form
|
||||
}
|
||||
|
||||
function parseHeaders(rawHeaders) {
|
||||
var headers = new Headers()
|
||||
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
|
||||
// https://tools.ietf.org/html/rfc7230#section-3.2
|
||||
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ')
|
||||
preProcessedHeaders.split(/\r?\n/).forEach(function(line) {
|
||||
var parts = line.split(':')
|
||||
var key = parts.shift().trim()
|
||||
if (key) {
|
||||
var value = parts.join(':').trim()
|
||||
headers.append(key, value)
|
||||
}
|
||||
})
|
||||
return headers
|
||||
}
|
||||
|
||||
Body.call(Request.prototype)
|
||||
|
||||
function Response(bodyInit, options) {
|
||||
if (!options) {
|
||||
options = {}
|
||||
}
|
||||
|
||||
this.type = 'default'
|
||||
this.status = options.status === undefined ? 200 : options.status
|
||||
this.ok = this.status >= 200 && this.status < 300
|
||||
this.statusText = 'statusText' in options ? options.statusText : 'OK'
|
||||
this.headers = new Headers(options.headers)
|
||||
this.url = options.url || ''
|
||||
this._initBody(bodyInit)
|
||||
}
|
||||
|
||||
Body.call(Response.prototype)
|
||||
|
||||
Response.prototype.clone = function() {
|
||||
return new Response(this._bodyInit, {
|
||||
status: this.status,
|
||||
statusText: this.statusText,
|
||||
headers: new Headers(this.headers),
|
||||
url: this.url
|
||||
})
|
||||
}
|
||||
|
||||
Response.error = function() {
|
||||
var response = new Response(null, {status: 0, statusText: ''})
|
||||
response.type = 'error'
|
||||
return response
|
||||
}
|
||||
|
||||
var redirectStatuses = [301, 302, 303, 307, 308]
|
||||
|
||||
Response.redirect = function(url, status) {
|
||||
if (redirectStatuses.indexOf(status) === -1) {
|
||||
throw new RangeError('Invalid status code')
|
||||
}
|
||||
|
||||
return new Response(null, {status: status, headers: {location: url}})
|
||||
}
|
||||
|
||||
self.Headers = Headers
|
||||
self.Request = Request
|
||||
self.Response = Response
|
||||
|
||||
self.fetch = function(input, init) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var request = new Request(input, init)
|
||||
var xhr = new XMLHttpRequest()
|
||||
|
||||
xhr.onload = function() {
|
||||
var options = {
|
||||
status: xhr.status,
|
||||
statusText: xhr.statusText,
|
||||
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
||||
}
|
||||
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL')
|
||||
var body = 'response' in xhr ? xhr.response : xhr.responseText
|
||||
resolve(new Response(body, options))
|
||||
}
|
||||
|
||||
xhr.onerror = function() {
|
||||
reject(new TypeError('Network request failed'))
|
||||
}
|
||||
|
||||
xhr.ontimeout = function() {
|
||||
reject(new TypeError('Network request failed'))
|
||||
}
|
||||
|
||||
xhr.open(request.method, request.url, true)
|
||||
|
||||
if (request.credentials === 'include') {
|
||||
xhr.withCredentials = true
|
||||
} else if (request.credentials === 'omit') {
|
||||
xhr.withCredentials = false
|
||||
}
|
||||
|
||||
if ('responseType' in xhr && support.blob) {
|
||||
xhr.responseType = 'blob'
|
||||
}
|
||||
|
||||
request.headers.forEach(function(value, name) {
|
||||
xhr.setRequestHeader(name, value)
|
||||
})
|
||||
|
||||
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit)
|
||||
})
|
||||
}
|
||||
self.fetch.polyfill = true
|
||||
})(typeof self !== 'undefined' ? self : this);
|
||||
@ -1,2 +0,0 @@
|
||||
import './fetch';
|
||||
import './url-search-params';
|
||||
@ -1,348 +0,0 @@
|
||||
(function(global) {
|
||||
/**
|
||||
* Polyfill URLSearchParams
|
||||
*
|
||||
* Inspired from : https://github.com/WebReflection/url-search-params/blob/master/src/url-search-params.js
|
||||
*/
|
||||
|
||||
var checkIfIteratorIsSupported = function() {
|
||||
try {
|
||||
return !!Symbol.iterator;
|
||||
} catch(error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var iteratorSupported = checkIfIteratorIsSupported();
|
||||
|
||||
var createIterator = function(items) {
|
||||
var iterator = {
|
||||
next: function() {
|
||||
var value = items.shift();
|
||||
return { done: value === void 0, value: value };
|
||||
}
|
||||
};
|
||||
|
||||
if(iteratorSupported) {
|
||||
iterator[Symbol.iterator] = function() {
|
||||
return iterator;
|
||||
};
|
||||
}
|
||||
|
||||
return iterator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Search param name and values should be encoded according to https://url.spec.whatwg.org/#urlencoded-serializing
|
||||
* encodeURIComponent() produces the same result except encoding spaces as `%20` instead of `+`.
|
||||
*/
|
||||
var serializeParam = function(value) {
|
||||
return encodeURIComponent(value).replace(/%20/g, '+');
|
||||
};
|
||||
|
||||
var deserializeParam = function(value) {
|
||||
return decodeURIComponent(value).replace(/\+/g, ' ');
|
||||
};
|
||||
|
||||
var polyfillURLSearchParams= function() {
|
||||
|
||||
var URLSearchParams = function(searchString) {
|
||||
Object.defineProperty(this, '_entries', { value: {} });
|
||||
|
||||
if(typeof searchString === 'string') {
|
||||
if(searchString !== '') {
|
||||
searchString = searchString.replace(/^\?/, '');
|
||||
var attributes = searchString.split('&');
|
||||
var attribute;
|
||||
for(var i = 0; i < attributes.length; i++) {
|
||||
attribute = attributes[i].split('=');
|
||||
this.append(
|
||||
deserializeParam(attribute[0]),
|
||||
(attribute.length > 1) ? deserializeParam(attribute[1]) : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if(searchString instanceof URLSearchParams) {
|
||||
var _this = this;
|
||||
searchString.forEach(function(value, name) {
|
||||
_this.append(value, name);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var proto = URLSearchParams.prototype;
|
||||
|
||||
proto.append = function(name, value) {
|
||||
if(name in this._entries) {
|
||||
this._entries[name].push(value.toString());
|
||||
} else {
|
||||
this._entries[name] = [value.toString()];
|
||||
}
|
||||
};
|
||||
|
||||
proto.delete = function(name) {
|
||||
delete this._entries[name];
|
||||
};
|
||||
|
||||
proto.get = function(name) {
|
||||
return (name in this._entries) ? this._entries[name][0] : null;
|
||||
};
|
||||
|
||||
proto.getAll = function(name) {
|
||||
return (name in this._entries) ? this._entries[name].slice(0) : [];
|
||||
};
|
||||
|
||||
proto.has = function(name) {
|
||||
return (name in this._entries);
|
||||
};
|
||||
|
||||
proto.set = function(name, value) {
|
||||
this._entries[name] = [value.toString()];
|
||||
};
|
||||
|
||||
proto.forEach = function(callback, thisArg) {
|
||||
var entries;
|
||||
for(var name in this._entries) {
|
||||
if(this._entries.hasOwnProperty(name)) {
|
||||
entries = this._entries[name];
|
||||
for(var i = 0; i < entries.length; i++) {
|
||||
callback.call(thisArg, entries[i], name, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
proto.keys = function() {
|
||||
var items = [];
|
||||
this.forEach(function(value, name) { items.push(name); });
|
||||
return createIterator(items);
|
||||
};
|
||||
|
||||
proto.values = function() {
|
||||
var items = [];
|
||||
this.forEach(function(value) { items.push(value); });
|
||||
return createIterator(items);
|
||||
};
|
||||
|
||||
proto.entries = function() {
|
||||
var items = [];
|
||||
this.forEach(function(value, name) { items.push([name, value]); });
|
||||
return createIterator(items);
|
||||
};
|
||||
|
||||
if(iteratorSupported) {
|
||||
proto[Symbol.iterator] = proto.entries;
|
||||
}
|
||||
|
||||
proto.toString = function() {
|
||||
var searchString = '';
|
||||
this.forEach(function(value, name) {
|
||||
if(searchString.length > 0) searchString+= '&';
|
||||
searchString += serializeParam(name) + '=' + serializeParam(value);
|
||||
});
|
||||
return searchString;
|
||||
};
|
||||
|
||||
global.URLSearchParams = URLSearchParams;
|
||||
};
|
||||
|
||||
if(!('URLSearchParams' in global) || (new URLSearchParams('?a=1').toString() !== 'a=1')) {
|
||||
polyfillURLSearchParams();
|
||||
}
|
||||
|
||||
// HTMLAnchorElement
|
||||
|
||||
})(
|
||||
(typeof global !== 'undefined') ? global
|
||||
: ((typeof window !== 'undefined') ? window
|
||||
: ((typeof self !== 'undefined') ? self : this))
|
||||
);
|
||||
|
||||
(function(global) {
|
||||
/**
|
||||
* Polyfill URL
|
||||
*
|
||||
* Inspired from : https://github.com/arv/DOM-URL-Polyfill/blob/master/src/url.js
|
||||
*/
|
||||
|
||||
var checkIfURLIsSupported = function() {
|
||||
try {
|
||||
var u = new URL('b', 'http://a');
|
||||
u.pathname = 'c%20d';
|
||||
return (u.href === 'http://a/c%20d') && u.searchParams;
|
||||
} catch(e) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var polyfillURL = function() {
|
||||
var _URL = global.URL;
|
||||
|
||||
var URL = function(url, base) {
|
||||
if(typeof url !== 'string') url = String(url);
|
||||
|
||||
var doc = document.implementation.createHTMLDocument('');
|
||||
window.doc = doc;
|
||||
if(base) {
|
||||
var baseElement = doc.createElement('base');
|
||||
baseElement.href = base;
|
||||
doc.head.appendChild(baseElement);
|
||||
}
|
||||
|
||||
var anchorElement = doc.createElement('a');
|
||||
anchorElement.href = url;
|
||||
doc.body.appendChild(anchorElement);
|
||||
anchorElement.href = anchorElement.href; // force href to refresh
|
||||
|
||||
if(anchorElement.protocol === ':' || !/:/.test(anchorElement.href)) {
|
||||
throw new TypeError('Invalid URL');
|
||||
}
|
||||
|
||||
Object.defineProperty(this, '_anchorElement', {
|
||||
value: anchorElement
|
||||
});
|
||||
};
|
||||
|
||||
var proto = URL.prototype;
|
||||
|
||||
var linkURLWithAnchorAttribute = function(attributeName) {
|
||||
Object.defineProperty(proto, attributeName, {
|
||||
get: function() {
|
||||
return this._anchorElement[attributeName];
|
||||
},
|
||||
set: function(value) {
|
||||
this._anchorElement[attributeName] = value;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
};
|
||||
|
||||
['hash', 'host', 'hostname', 'port', 'protocol', 'search']
|
||||
.forEach(function(attributeName) {
|
||||
linkURLWithAnchorAttribute(attributeName);
|
||||
});
|
||||
|
||||
Object.defineProperties(proto, {
|
||||
|
||||
'toString': {
|
||||
get: function() {
|
||||
var _this = this;
|
||||
return function() {
|
||||
return _this.href;
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
'href' : {
|
||||
get: function() {
|
||||
return this._anchorElement.href.replace(/\?$/,'');
|
||||
},
|
||||
set: function(value) {
|
||||
this._anchorElement.href = value;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
'pathname' : {
|
||||
get: function() {
|
||||
return this._anchorElement.pathname.replace(/(^\/?)/,'/');
|
||||
},
|
||||
set: function(value) {
|
||||
this._anchorElement.pathname = value;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
'origin': {
|
||||
get: function() {
|
||||
// get expected port from protocol
|
||||
var expectedPort = {'http:': 80, 'https:': 443, 'ftp:': 21}[this._anchorElement.protocol];
|
||||
// add port to origin if, expected port is different than actual port
|
||||
// and it is not empty f.e http://foo:8080
|
||||
// 8080 != 80 && 8080 != ''
|
||||
var addPortToOrigin = this._anchorElement.port != expectedPort &&
|
||||
this._anchorElement.port !== ''
|
||||
|
||||
return this._anchorElement.protocol +
|
||||
'//' +
|
||||
this._anchorElement.hostname +
|
||||
(addPortToOrigin ? (':' + this._anchorElement.port) : '');
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
'password': { // TODO
|
||||
get: function() {
|
||||
return '';
|
||||
},
|
||||
set: function(value) {
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
'username': { // TODO
|
||||
get: function() {
|
||||
return '';
|
||||
},
|
||||
set: function(value) {
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
|
||||
'searchParams': {
|
||||
get: function() {
|
||||
var searchParams = new URLSearchParams(this.search);
|
||||
var _this = this;
|
||||
['append', 'delete', 'set'].forEach(function(methodName) {
|
||||
var method = searchParams[methodName];
|
||||
searchParams[methodName] = function() {
|
||||
method.apply(searchParams, arguments);
|
||||
_this.search = searchParams.toString();
|
||||
};
|
||||
});
|
||||
return searchParams;
|
||||
},
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
|
||||
URL.createObjectURL = function(blob) {
|
||||
return _URL.createObjectURL.apply(_URL, arguments);
|
||||
};
|
||||
|
||||
URL.revokeObjectURL = function(url) {
|
||||
return _URL.revokeObjectURL.apply(_URL, arguments);
|
||||
};
|
||||
|
||||
global.URL = URL;
|
||||
|
||||
};
|
||||
|
||||
if(!checkIfURLIsSupported()) {
|
||||
polyfillURL();
|
||||
}
|
||||
|
||||
if((global.location !== void 0) && !('origin' in global.location)) {
|
||||
var getOrigin = function() {
|
||||
return global.location.protocol + '//' + global.location.hostname + (global.location.port ? (':' + global.location.port) : '');
|
||||
};
|
||||
|
||||
try {
|
||||
Object.defineProperty(global.location, 'origin', {
|
||||
get: getOrigin,
|
||||
enumerable: true
|
||||
});
|
||||
} catch(e) {
|
||||
setInterval(function() {
|
||||
global.location.origin = getOrigin();
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
})(
|
||||
(typeof global !== 'undefined') ? global
|
||||
: ((typeof window !== 'undefined') ? window
|
||||
: ((typeof self !== 'undefined') ? self : this))
|
||||
);
|
||||
@ -4,6 +4,9 @@ import { I18n } from './services/i18n/i18n';
|
||||
import { UtilRegistry } from './services/util-registry/util-registry';
|
||||
import { isValidUtility } from './core/utility';
|
||||
|
||||
// load window.fetch polyfill
|
||||
import 'whatwg-fetch';
|
||||
|
||||
export class App {
|
||||
httpClient = new HttpClient();
|
||||
htmlHelpers = new HtmlHelpers();
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import './async-form.scss';
|
||||
|
||||
const ASYNC_FORM_INITIALIZED_CLASS = 'check-all--initialized';
|
||||
@ -70,7 +71,9 @@ export class AsyncForm {
|
||||
|
||||
const url = this._element.getAttribute('action');
|
||||
const headers = { };
|
||||
const body = new FormData(this._element);
|
||||
|
||||
// create new FormData and format any date values
|
||||
const body = Datepicker.unformatAll(this._element, new FormData(this._element));
|
||||
|
||||
const isModal = this._element.closest(MODAL_SELECTOR);
|
||||
if (isModal) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
import { HttpClient } from '../../services/http-client/http-client';
|
||||
import * as debounce from 'lodash.debounce';
|
||||
import './async-table-filter.scss';
|
||||
@ -238,6 +239,10 @@ export class AsyncTable {
|
||||
|
||||
_serializeTableFilterToURL(tableFilterForm) {
|
||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||
|
||||
// format any date values before submission
|
||||
Datepicker.destroyAllFormInputDates(tableFilterForm);
|
||||
|
||||
const formData = new FormData(tableFilterForm);
|
||||
|
||||
for (var k of url.searchParams.keys()) {
|
||||
@ -298,7 +303,9 @@ export class AsyncTable {
|
||||
|
||||
_changePagesizeHandler = () => {
|
||||
const url = new URL(getLocalStorageParameter('currentTableUrl') || window.location.href);
|
||||
const formData = new FormData(this._pagesizeForm);
|
||||
|
||||
// create new FormData and format any date values
|
||||
const formData = Datepicker.unformatAll(this._pagesizeForm, new FormData(this._pagesizeForm));
|
||||
|
||||
for (var k of url.searchParams.keys()) {
|
||||
url.searchParams.delete(k);
|
||||
|
||||
@ -1,30 +1,90 @@
|
||||
import flatpickr from 'flatpickr';
|
||||
import datetime from 'tail.datetime';
|
||||
import { Utility } from '../../core/utility';
|
||||
import moment from 'moment';
|
||||
|
||||
const KEYCODE_ESCAPE = 27;
|
||||
|
||||
// INTERNAL (Uni2work specific) formats for formatting dates and/or times
|
||||
const FORM_DATE_FORMAT = {
|
||||
'date': moment.HTML5_FMT.DATE,
|
||||
'time': moment.HTML5_FMT.TIME_SECONDS,
|
||||
'datetime-local': moment.HTML5_FMT.DATETIME_LOCAL_SECONDS,
|
||||
};
|
||||
|
||||
// FANCY (tail.datetime specific) formats for displaying dates and/or times
|
||||
const FORM_DATE_FORMAT_DATE_DT = 'dd.mm.YYYY';
|
||||
const FORM_DATE_FORMAT_TIME_DT = 'HH:ii:ss';
|
||||
|
||||
// FANCY (moment specific) formats for displaying dates and/or times
|
||||
const FORM_DATE_FORMAT_DATE_MOMENT = 'DD.MM.YYYY';
|
||||
const FORM_DATE_FORMAT_TIME_MOMENT = 'HH:mm:ss';
|
||||
const FORM_DATE_FORMAT_MOMENT = {
|
||||
'date': FORM_DATE_FORMAT_DATE_MOMENT,
|
||||
'time': FORM_DATE_FORMAT_TIME_MOMENT,
|
||||
'datetime-local': `${FORM_DATE_FORMAT_DATE_MOMENT} ${FORM_DATE_FORMAT_TIME_MOMENT}`,
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a string representation of a date and a format string and parses the given date to a Date object.
|
||||
* If the date string is not valid (i.e. cannot be parsed with the given format string), returns undefined.
|
||||
* @param {*} dateStr string representation of a date
|
||||
* @param {*} dateFormat format string of the date
|
||||
*/
|
||||
function parseDateWithFormat(dateStr, dateFormat) {
|
||||
const parsedMomentDate = moment(dateStr, dateFormat);
|
||||
if (parsedMomentDate.isValid()) return parsedMomentDate.toDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a string representation of a date, an input ('previous') format and a desired output format and returns a reformatted date string.
|
||||
* If the date string is not valid (i.e. cannot be parsed with the given input format string), returns the original date string;
|
||||
* @param {*} dateStr string representation of a date (needs to be in format formatIn)
|
||||
* @param {*} formatIn input format string
|
||||
* @param {*} formatOut format string of the desired output date string
|
||||
*/
|
||||
function reformatDateString(dateStr, formatIn, formatOut) {
|
||||
const parsedMomentDate = moment(dateStr, formatIn);
|
||||
return parsedMomentDate.isValid() ? parsedMomentDate.format(formatOut) : dateStr;
|
||||
}
|
||||
|
||||
const DATEPICKER_UTIL_SELECTOR = 'input[type="date"], input[type="time"], input[type="datetime-local"]';
|
||||
|
||||
const DATEPICKER_INITIALIZED_CLASS = 'datepicker--initialized';
|
||||
|
||||
const DATEPICKER_CONFIG = {
|
||||
'datetime-local': {
|
||||
enableTime: true,
|
||||
altInput: true,
|
||||
altFormat: 'j. F Y, H:i', // maybe interpolate these formats for locale
|
||||
dateFormat: 'Y-m-dTH:i',
|
||||
time_24hr: true,
|
||||
'global': {
|
||||
// minimize overlaps with other date inputs
|
||||
position: 'right',
|
||||
|
||||
// set default time to 00:00:00
|
||||
timeHours: 0,
|
||||
timeMinutes: 0,
|
||||
timeSeconds: 0,
|
||||
|
||||
// german settings
|
||||
// TODO: hardcoded, get from current language / settings
|
||||
locale: 'de',
|
||||
weekStart: 1,
|
||||
dateFormat: FORM_DATE_FORMAT_DATE_DT,
|
||||
timeFormat: FORM_DATE_FORMAT_TIME_DT,
|
||||
|
||||
// prevent the instance from closing when selecting a date before selecting a time
|
||||
stayOpen: true,
|
||||
|
||||
// hide the close button (we handle closing the datepicker manually by clicking outside)
|
||||
closeButton: false,
|
||||
|
||||
// disable the decades view because nobody will ever need it (i.e. cap the switch to the more relevant year view)
|
||||
viewDecades: false,
|
||||
},
|
||||
'datetime-local': {},
|
||||
'date': {
|
||||
altFormat: 'j. F Y',
|
||||
dateFormat: 'Y-m-d',
|
||||
altInput: true,
|
||||
// disable date picker
|
||||
timeFormat: false,
|
||||
},
|
||||
'time': {
|
||||
enableTime: true,
|
||||
noCalendar: true,
|
||||
altFormat: 'H:i',
|
||||
dateFormat: 'H:i',
|
||||
altInput: true,
|
||||
time_24hr: true,
|
||||
// disable time picker
|
||||
dateFormat: false,
|
||||
},
|
||||
};
|
||||
|
||||
@ -33,7 +93,12 @@ const DATEPICKER_CONFIG = {
|
||||
})
|
||||
export class Datepicker {
|
||||
|
||||
flatpickrInstance;
|
||||
// singleton Map that maps a formID to a Map of Datepicker objects
|
||||
static datepickerCollections;
|
||||
|
||||
datepickerInstance;
|
||||
_element;
|
||||
elementType;
|
||||
|
||||
constructor(element) {
|
||||
if (!element) {
|
||||
@ -44,19 +109,140 @@ export class Datepicker {
|
||||
return false;
|
||||
}
|
||||
|
||||
const flatpickrConfig = DATEPICKER_CONFIG[element.getAttribute('type')];
|
||||
// initialize datepickerCollections singleton if not already done
|
||||
if (!Datepicker.datepickerCollections) {
|
||||
Datepicker.datepickerCollections = new Map();
|
||||
}
|
||||
|
||||
if (!flatpickrConfig) {
|
||||
this._element = element;
|
||||
|
||||
// store the previously set type to select the input format
|
||||
this.elementType = this._element.getAttribute('type');
|
||||
|
||||
// get all relevant config options for this datepicker type
|
||||
const datepickerGlobalConfig = DATEPICKER_CONFIG['global'];
|
||||
const datepickerConfig = DATEPICKER_CONFIG[this.elementType];
|
||||
|
||||
// manually set the type attribute to text because datepicker handles displaying the date
|
||||
this._element.setAttribute('type', 'text');
|
||||
|
||||
// additional position config (optional data-datepicker-position attribute in html) that can specialize the global config
|
||||
const datepickerPosition = this._element.dataset.datepickerPosition;
|
||||
if (datepickerPosition) {
|
||||
datepickerGlobalConfig.position = datepickerPosition;
|
||||
}
|
||||
|
||||
if (!datepickerConfig || !FORM_DATE_FORMAT[this.elementType]) {
|
||||
throw new Error('Datepicker utility called on unsupported element!');
|
||||
}
|
||||
|
||||
this.flatpickrInstance = flatpickr(element, flatpickrConfig);
|
||||
// initialize tail.datetime (datepicker) instance
|
||||
this.datepickerInstance = datetime(this._element, { ...datepickerGlobalConfig, ...datepickerConfig });
|
||||
|
||||
// mark initialized
|
||||
element.classList.add(DATEPICKER_INITIALIZED_CLASS);
|
||||
// register this datepicker instance with the formID of the given element in the datepicker collection
|
||||
const formID = this._element.form.id;
|
||||
const elemID = this._element.id;
|
||||
if (!Datepicker.datepickerCollections.has(formID)) {
|
||||
// insert a new key value pair if the formID key is not there already
|
||||
Datepicker.datepickerCollections.set(formID, new Map([[elemID, this]]));
|
||||
} else {
|
||||
// otherwise, insert this instance into the Map
|
||||
Datepicker.datepickerCollections.get(formID).set(elemID, this);
|
||||
}
|
||||
|
||||
// mark the form input element as initialized
|
||||
this._element.classList.add(DATEPICKER_INITIALIZED_CLASS);
|
||||
|
||||
const setDatepickerDate = () => {
|
||||
// try to parse the current input element value with fancy and internal format string
|
||||
const parsedMomentDate = moment(this._element.value, FORM_DATE_FORMAT_MOMENT[this.elementType]);
|
||||
const parsedMomentDateInternal = moment(this._element.value, FORM_DATE_FORMAT[this.elementType]);
|
||||
|
||||
// only set the datepicker date if the input is either in valid fancy format or in valid internal format
|
||||
if (parsedMomentDate.isValid()) {
|
||||
this.datepickerInstance.selectDate(parsedMomentDate.toDate());
|
||||
} else if (parsedMomentDateInternal.isValid()) {
|
||||
this.datepickerInstance.selectDate(parsedMomentDateInternal.toDate());
|
||||
}
|
||||
|
||||
// reregister change event to prevent event loop
|
||||
this._element.addEventListener('change', setDatepickerDate, { once: true });
|
||||
};
|
||||
// change the selected date in the tail.datetime instance if the value of the input element is changed
|
||||
this._element.addEventListener('change', setDatepickerDate, { once: true });
|
||||
|
||||
// close the instance if something other than the instance was clicked (i.e. if the target is not within the datepicker instance and if any previously clicked calendar view was replaced (is not in the window anymore) because it was clicked). YES, I KNOW
|
||||
window.addEventListener('click', event => {
|
||||
if (!this.datepickerInstance.dt.contains(event.target) && window.document.contains(event.target)) {
|
||||
this.datepickerInstance.close();
|
||||
}
|
||||
});
|
||||
|
||||
// close the datepicker on escape keydown events
|
||||
this._element.addEventListener('keydown', event => {
|
||||
if (event.keyCode === KEYCODE_ESCAPE) {
|
||||
this.datepickerInstance.close();
|
||||
}
|
||||
});
|
||||
|
||||
// format the date value of the form input element of this datepicker before form submission
|
||||
this._element.form.addEventListener('submit', () => this.formatElementValue());
|
||||
|
||||
// format any existing dates to fancy display format on pageload
|
||||
this.formatElementValue(true);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.flatpickrInstance.destroy();
|
||||
this.datepickerInstance.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the value of this input element from datepicker format (i.e. DATEPICKER_CONFIG.dateFormat + " " + datetime.defaults.timeFormat) to Uni2work internal date format (i.e. FORM_DATE_FORMAT) required for form submission
|
||||
* @param {*} toFancy optional target format switch (boolean value; default is false). If set to a truthy value, formats the element value to fancy instead of internal date format.
|
||||
*/
|
||||
formatElementValue(toFancy) {
|
||||
const dp = this.datepickerInstance;
|
||||
if (this._element.value) {
|
||||
if (toFancy) {
|
||||
const parsedDate = parseDateWithFormat(this._element.value, FORM_DATE_FORMAT[this.elementType]);
|
||||
if (parsedDate) dp.selectDate();
|
||||
} else {
|
||||
this._element.value = this.unformat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a datestring in internal format from the current state of the input element value.
|
||||
*/
|
||||
unformat() {
|
||||
return reformatDateString(this._element.value, FORM_DATE_FORMAT_MOMENT[this.elementType], FORM_DATE_FORMAT[this.elementType]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a Form and a FormData and returns a new FormData with all dates formatted to uni2work date format. This function will not change the value of the date input elements.
|
||||
* @param {*} form Form for which all dates will be formatted in the FormData
|
||||
* @param {*} formData Initial FormData
|
||||
*/
|
||||
static unformatAll(form, formData) {
|
||||
// only proceed if there are any datepickers and if both form and formData are defined
|
||||
if (Datepicker.datepickerCollections && form && formData) {
|
||||
// if the form has no id, assign one randomly
|
||||
if (!form.id) {
|
||||
form.id = `f${Math.floor(Math.random() * 100000)}`;
|
||||
}
|
||||
|
||||
const formId = form.id;
|
||||
|
||||
if (Datepicker.datepickerCollections.has(formId)) {
|
||||
const datepickerInstances = Datepicker.datepickerCollections.get(formId);
|
||||
datepickerInstances.forEach(instance => {
|
||||
formData.set(instance._element.name, instance.unformat());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// return the (possibly changed) FormData
|
||||
return formData;
|
||||
}
|
||||
}
|
||||
@ -6,3 +6,9 @@ Provides UI for entering dates and times
|
||||
|
||||
## Example usage:
|
||||
(any form that uses inputs of type date, time, or datetime-local)
|
||||
|
||||
## Methods
|
||||
|
||||
### static unformatAll(form, formData)
|
||||
|
||||
Call this function on a form and its formData to get back a new FormData object with "unformatted" date values (i.e. all dates formatted from fancy format to backend format).
|
||||
@ -2,6 +2,16 @@ import { Utility } from '../../core/utility';
|
||||
import { AUTO_SUBMIT_BUTTON_UTIL_SELECTOR } from './auto-submit-button';
|
||||
import { AUTO_SUBMIT_INPUT_UTIL_SELECTOR } from './auto-submit-input';
|
||||
|
||||
/**
|
||||
* Key generator from an arbitrary number of FormData objects.
|
||||
* @param {...any} formDatas FormData objects
|
||||
*/
|
||||
function* generatorFromFormDatas(...formDatas) {
|
||||
for (let formData of formDatas) {
|
||||
yield* formData.keys();
|
||||
}
|
||||
}
|
||||
|
||||
const NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS = 'navigate-away-prompt--initialized';
|
||||
const NAVIGATE_AWAY_PROMPT_UTIL_OPTOUT = '[uw-no-navigate-away-prompt]';
|
||||
|
||||
@ -12,7 +22,7 @@ export class NavigateAwayPrompt {
|
||||
|
||||
_element;
|
||||
|
||||
_touched = false;
|
||||
_initFormData;
|
||||
_unloadDueToSubmit = false;
|
||||
|
||||
constructor(element) {
|
||||
@ -21,6 +31,7 @@ export class NavigateAwayPrompt {
|
||||
}
|
||||
|
||||
this._element = element;
|
||||
this._initFormData = new FormData(this._element);
|
||||
|
||||
if (this._element.classList.contains(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
@ -40,10 +51,6 @@ export class NavigateAwayPrompt {
|
||||
this._element.addEventListener('submit', () => {
|
||||
this._unloadDueToSubmit = true;
|
||||
});
|
||||
this._element.addEventListener('change', () => {
|
||||
this._touched = true;
|
||||
this._unloadDueToSubmit = false;
|
||||
});
|
||||
|
||||
// mark initialized
|
||||
this._element.classList.add(NAVIGATE_AWAY_PROMPT_INITIALIZED_CLASS);
|
||||
@ -55,9 +62,20 @@ export class NavigateAwayPrompt {
|
||||
}
|
||||
|
||||
_beforeUnloadHandler = (event) => {
|
||||
// compare every value of the current FormData with every corresponding value of the initial FormData and set formDataHasChanged to true if there is at least one change
|
||||
const currentFormData = new FormData(this._element);
|
||||
var formDataHasChanged = false;
|
||||
for (let key of generatorFromFormDatas(this._initFormData, currentFormData)) {
|
||||
if (currentFormData.get(key) !== this._initFormData.get(key)) {
|
||||
formDataHasChanged = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// allow the event to happen if the form was not touched by the
|
||||
// user or the unload event was initiated by a form submit
|
||||
if (!this._touched || this._unloadDueToSubmit) {
|
||||
// user (i.e. if the current FormData is equal to the initial FormData)
|
||||
// or the unload event was initiated by a form submit
|
||||
if (!formDataHasChanged || this._unloadDueToSubmit) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import { Datepicker } from '../form/datepicker';
|
||||
|
||||
const MASS_INPUT_CELL_SELECTOR = '.massinput__cell';
|
||||
const MASS_INPUT_ADD_CELL_SELECTOR = '.massinput__cell--add';
|
||||
@ -157,7 +158,8 @@ export class MassInput {
|
||||
}
|
||||
|
||||
_serializeForm(submitButton, enctype) {
|
||||
const formData = new FormData(this._massInputForm);
|
||||
// create new FormData and format any date values
|
||||
const formData = Datepicker.unformatAll(this._massInputForm, new FormData(this._massInputForm));
|
||||
|
||||
// manually add name and value of submit button to formData
|
||||
formData.append(submitButton.name, submitButton.value);
|
||||
|
||||
727
frontend/vendor/datetime.css
vendored
Normal file
727
frontend/vendor/datetime.css
vendored
Normal file
@ -0,0 +1,727 @@
|
||||
@charset "UTF-8";
|
||||
/*
|
||||
| tail.datetime - The vanilla way to select dates and times!
|
||||
| @file ./less/tail.datetime-default-green.less
|
||||
| @author SamBrishes <sam@pytes.net>
|
||||
| @version 0.4.13 - Beta
|
||||
|
|
||||
| @website https://github.com/pytesNET/tail.DateTime
|
||||
| @license X11 / MIT License
|
||||
| @copyright Copyright © 2018 - 2019 SamBrishes, pytesNET <info@pytes.net>
|
||||
*/
|
||||
|
||||
/* @start MAIN CALENDAR */
|
||||
.tail-datetime-calendar, .tail-datetime-calendar *, .tail-datetime-calendar *:before,
|
||||
.tail-datetime-calendar *:after{
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
.tail-datetime-calendar{
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 275px;
|
||||
height: auto;
|
||||
margin: 15px;
|
||||
padding: 0;
|
||||
z-index: 15;
|
||||
display: block;
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
direction: ltr;
|
||||
border-collapse: separate;
|
||||
font-family: "Open Sans", Calibri, Arial, sans-serif;
|
||||
background-color: white;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3125);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3125);
|
||||
}
|
||||
.tail-datetime-calendar:after{
|
||||
clear: both;
|
||||
content: "";
|
||||
display: block;
|
||||
font-size: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
.tail-datetime-calendar.calendar-static{
|
||||
top: auto;
|
||||
left: auto;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
position: static;
|
||||
visibility: visible;
|
||||
}
|
||||
.tail-datetime-calendar button.calendar-close{
|
||||
top: 100%;
|
||||
right: 15px;
|
||||
color: #303438;
|
||||
width: 35px;
|
||||
height: 25px;
|
||||
margin: 1px 0 0 0;
|
||||
padding: 5px 10px;
|
||||
opacity: 0.5;
|
||||
outline: none;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
line-height: 1.125em;
|
||||
text-shadow: none;
|
||||
background-color: white;
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC\
|
||||
9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjMzAzNDM4IiBkP\
|
||||
SJNNy40OCA4bDMuNzUgMy43NS0xLjQ4IDEuNDhMNiA5LjQ4bC0zLjc1IDMuNzUtMS40OC0xLjQ4TDQuNTIgOCAuNzcgNC4y\
|
||||
NWwxLjQ4LTEuNDhMNiA2LjUybDMuNzUtMy43NSAxLjQ4IDEuNDhMNy40OCA4eiIvPjwvc3ZnPg==");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 0 0 3px 3px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3125);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3125);
|
||||
transition: opacity 142ms linear;
|
||||
-webkit-transition: opacity 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar button.calendar-close:hover{
|
||||
opacity: 1;
|
||||
}
|
||||
/* @end MAIN CALENDAR */
|
||||
|
||||
/* @start CALENDAR TOOLTIP */
|
||||
.tail-datetime-calendar .calendar-tooltip{
|
||||
color: white;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
background-color: #202428;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-tooltip:before{
|
||||
top: -7px;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0 0 0 -6px;
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
border-width: 0 7px 7px 7px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent #202428 transparent;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-tooltip .tooltip-inner{
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 4px 7px;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 14px;
|
||||
}
|
||||
/* @end CALENDAR TOOLTIP */
|
||||
|
||||
/* @start CALENDAR ACTIONs */
|
||||
.tail-datetime-calendar .calendar-actions{
|
||||
color: white;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: table;
|
||||
overflow: hidden;
|
||||
border-spacing: 0;
|
||||
border-collapse: separate;
|
||||
background-color: var(--color-primary);
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 3px 3px 0 0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: table-cell;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
text-shadow: -1px -1px 0 var(--color-dark);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span[data-action]{
|
||||
cursor: pointer;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.action{
|
||||
width: 36px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.label{
|
||||
width: auto;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span:first-child:before{
|
||||
right: -1px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span:last-child:before{
|
||||
left: -1px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span:first-child:hover:before,
|
||||
.tail-datetime-calendar .calendar-actions span:last-child:hover:before{
|
||||
display: none;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span[data-action]:hover{
|
||||
background-color: var(--color-dark);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.action-prev{
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC\
|
||||
9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgNiAxNiI+PHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iT\
|
||||
TYgMkwwIDhsNiA2VjJ6Ii8+PC9zdmc+");
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.action-next{
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC\
|
||||
9zdmciIHdpZHRoPSI2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgNiAxNiI+PHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iT\
|
||||
TAgMTRsNi02LTYtNnYxMnoiLz48L3N2Zz4=");
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.action-submit{
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC\
|
||||
9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjZmZmZmZmIiBkP\
|
||||
SJNMTIgNWwtOCA4LTQtNCAxLjUtMS41TDQgMTBsNi41LTYuNUwxMiA1eiIvPjwvc3ZnPg==");
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions span.action-cancel{
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC\
|
||||
9zdmciIHdpZHRoPSIxMiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDEyIDE2Ij48cGF0aCBmaWxsPSIjZmZmZmZmIiBkP\
|
||||
SJNNy40OCA4bDMuNzUgMy43NS0xLjQ4IDEuNDhMNiA5LjQ4bC0zLjc1IDMuNzUtMS40OC0xLjQ4TDQuNTIgOCAuNzcgNC4y\
|
||||
NWwxLjQ4LTEuNDhMNiA2LjUybDMuNzUtMy43NSAxLjQ4IDEuNDhMNy40OCA4eiIvPjwvc3ZnPg==");
|
||||
}
|
||||
/* @end CALENDAR ACTIONs */
|
||||
|
||||
/* @start CALENDAR DATEPICKER */
|
||||
.tail-datetime-calendar .calendar-datepicker{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-spacing: 0;
|
||||
border-collapse: separate;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td{
|
||||
color: #303438;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
font-weight: normal;
|
||||
text-shadow: none;
|
||||
line-height: 30px;
|
||||
background-color: transparent;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th{
|
||||
color: white;
|
||||
background-color: var(--color-lightblack);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td{
|
||||
cursor: pointer;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td span.inner{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-disabled{
|
||||
cursor: not-allowed;
|
||||
color: #909498;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-disabled:after{
|
||||
left: 3px;
|
||||
bottom: 3px;
|
||||
width: 35px;
|
||||
height: 1px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
background-color: #bfbfbf;
|
||||
transform-origin: 2px -5px;
|
||||
transform: rotate(-45deg);
|
||||
-moz-transform: rotate(-45deg);
|
||||
-webkit-transform: rotate(-45deg);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-previous,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-next{
|
||||
color: #909498;
|
||||
background-color: #F0F0F0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-today:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick{
|
||||
top: 5px;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 20;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.date-today:before{
|
||||
left: 5px;
|
||||
background-color: #E67D1E;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick{
|
||||
right: 5px;
|
||||
background-color: #202428;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td .tooltip-tick:after{
|
||||
display: none;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day{
|
||||
width: 14.28571429%;
|
||||
height: 35px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day span.inner{
|
||||
width: 31px;
|
||||
height: 31px;
|
||||
line-height: 29px;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week:hover span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day:hover span.inner{
|
||||
border-color: #cccccc;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-disabled span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-disabled span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-disabled:hover span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-disabled:hover span.inner{
|
||||
border-color: transparent;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-select span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-select span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr th.calendar-week.date-select:hover span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-day.date-select:hover span.inner{
|
||||
color: var(--color-fontsec);
|
||||
border-color: var(--color-fontsec);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade{
|
||||
width: 33.33333333%;
|
||||
height: 40px;
|
||||
transition: color 142ms linear;
|
||||
-webkit-transition: color 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month.date-today:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year.date-today:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade.date-today:before{
|
||||
left: 50%;
|
||||
margin-left: -2.5px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner{
|
||||
width: auto;
|
||||
height: 31px;
|
||||
line-height: 29px;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:after{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
content: "";
|
||||
z-index: 15;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
transition: all 142ms linear;
|
||||
-webkit-transition: all 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:before{
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month:hover span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year:hover span.inner:before,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade:hover span.inner:before{
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
border-top-color: #cccccc;
|
||||
border-left-color: #cccccc;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner:after{
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-month:hover span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year:hover span.inner:after,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade:hover span.inner:after{
|
||||
right: 6px;
|
||||
bottom: 6px;
|
||||
border-right-color: #cccccc;
|
||||
border-bottom-color: #cccccc;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-year,
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade{
|
||||
width: 25%;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-datepicker table tr td.calendar-decade span.inner{
|
||||
height: 54px;
|
||||
padding: 7px 15px;
|
||||
text-align: left;
|
||||
line-height: 20px;
|
||||
}
|
||||
/* @end CALENDAR DATEPICKER */
|
||||
|
||||
/* @start CALENDAR TIMEPICKER */
|
||||
.tail-datetime-calendar .calendar-timepicker{
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
text-align: center;
|
||||
border-width: 1px 0 0 0;
|
||||
border-style: solid;
|
||||
border-color: #d9d9d9;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field{
|
||||
width: 28%;
|
||||
margin: 0;
|
||||
padding: 15px 0 7px 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field:first-of-type{
|
||||
text-align: right;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field:last-of-type{
|
||||
text-align: left;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type="text"]{
|
||||
color: #303438;
|
||||
width: 100%;
|
||||
height: 29px;
|
||||
margin: 0;
|
||||
z-index: 4;
|
||||
padding: 3px 20px 3px 5px;
|
||||
outline: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
line-height: 23px;
|
||||
appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
-webkit-appearance: textfield;
|
||||
background-color: #F0F0F0;
|
||||
border-width: 0;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
border-radius: 3px;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
transition: color 142ms linear, border 142ms linear, background 142ms linear;
|
||||
-webkit-transition: color 142ms linear, border 142ms linear, background 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type="text"]:hover{
|
||||
color: #303438;
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type="text"]:focus{
|
||||
color: #303438;
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input[type="text"]:disabled{
|
||||
cursor: not-allowed;
|
||||
color: #A0A4A8;
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step{
|
||||
min-width: 0px;
|
||||
width: 20px;
|
||||
height: 15px;
|
||||
right: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 15;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
background-color: #F0F0F0;
|
||||
box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
transition: border 142ms linear, background 142ms linear;
|
||||
-webkit-transition: border 142ms linear, background 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step:before{
|
||||
top: 4px;
|
||||
left: 50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin: 0 0 0 -4px;
|
||||
padding: 0;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
transition: border 142ms linear;
|
||||
-webkit-transition: border 142ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up{
|
||||
top: 15px;
|
||||
border-width: 0 0 1px 1px;
|
||||
border-style: solid;
|
||||
border-color: white;
|
||||
border-radius: 0 2px 0 0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up:hover{
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-up:before{
|
||||
border-width: 0 4px 5px 4px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent #303438 transparent;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down{
|
||||
top: 29px;
|
||||
border-width: 1px 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: white;
|
||||
border-radius: 0 0 2px 0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down:hover{
|
||||
background-color: #E0E0E0;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field button.picker-step.step-down:before{
|
||||
border-width: 5px 4px 0 4px;
|
||||
border-style: solid;
|
||||
border-color: #303438 transparent transparent transparent;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button.step-up{
|
||||
border-color: rgba(255, 255, 255, 0.8);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button.step-up:hover{
|
||||
background-color: var(--color-dark);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button.step-up:before{
|
||||
border-bottom-color: white;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button + button.step-down{
|
||||
border-color: rgba(255, 255, 255, 0.8);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button + button.step-down:hover{
|
||||
background-color: var(--color-dark);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:focus + button + button.step-down:before{
|
||||
border-top-color: white;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button.step-up{
|
||||
cursor: not-allowed;
|
||||
border-color: rgba(255, 255, 255, 0.8);
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button.step-up:hover{
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button.step-up:before{
|
||||
border-bottom-color: #A0A4A8;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button + button.step-down{
|
||||
cursor: not-allowed;
|
||||
border-color: rgba(255, 255, 255, 0.8);
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button + button.step-down:hover{
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field input:disabled + button + button.step-down:before{
|
||||
border-top-color: #A0A4A8;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker .timepicker-field label{
|
||||
color: #303438;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch{
|
||||
cursor: pointer;
|
||||
margin: 15px 0 -5px 0;
|
||||
display: block;
|
||||
text-align: center;
|
||||
vertical-align: top;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:before,
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:after{
|
||||
width: auto;
|
||||
margin: 0;
|
||||
padding: 0 5px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
vertical-align: top;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:before{
|
||||
content: attr(data-am);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch:after{
|
||||
content: attr(data-pm);
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"]{
|
||||
display: none;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"] + span{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"] + span:before{
|
||||
width: 50px;
|
||||
height: 16px;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: var(--color-primary);
|
||||
border-radius: 14px;
|
||||
transition: border 284ms linear;
|
||||
-webkit-transition: border 284ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"] + span:after{
|
||||
top: 3px;
|
||||
left: 4px;
|
||||
right: 30px;
|
||||
width: auto;
|
||||
height: 10px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
background-color: var(--color-primary);
|
||||
border-radius: 15px;
|
||||
vertical-align: top;
|
||||
transition: left 284ms linear, right 284ms linear 284ms, background 284ms linear;
|
||||
-webkit-transition: left 284ms linear, right 284ms linear 284ms, background 284ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"]:checked + span:before{
|
||||
border-color: #E67D1E;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-timepicker label.timepicker-switch input[type="checkbox"]:checked + span:after{
|
||||
left: 30px;
|
||||
right: 4px;
|
||||
background-color: #E67D1E;
|
||||
transition: right 284ms linear, left 284ms linear 284ms, background 284ms linear;
|
||||
-webkit-transition: right 284ms linear, left 284ms linear 284ms, background 284ms linear;
|
||||
}
|
||||
.tail-datetime-calendar .calendar-actions + .calendar-timepicker{
|
||||
border-width: 0;
|
||||
}
|
||||
/* @end CALENDAR TIMEPICKER */
|
||||
|
||||
/* @start RTL */
|
||||
.tail-datetime-calendar.rtl{
|
||||
direction: rtl;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-actions span.action-next,
|
||||
.tail-datetime-calendar.rtl .calendar-actions span.action-prev{
|
||||
transform: rotate(180deg);
|
||||
-moz-transform: rotate(180deg);
|
||||
-webkit-transform: rotate(180deg);
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.date-disabled:after{
|
||||
right: 3px;
|
||||
transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-webkit-transform: rotate(45deg);
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.date-today:before{
|
||||
right: 5px;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td .tooltip-tick{
|
||||
left: 5px;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month.date-today:before,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year.date-today:before,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade.date-today:before{
|
||||
right: 50%;
|
||||
margin-right: -2.5px;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month:hover span.inner:before,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year:hover span.inner:before,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade:hover span.inner:before{
|
||||
right: 6px;
|
||||
border-right-color: #cccccc;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month span.inner:after,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year span.inner:after,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade span.inner:after{
|
||||
left: 0;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-month:hover span.inner:after,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-year:hover span.inner:after,
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade:hover span.inner:after{
|
||||
left: 6px;
|
||||
border-left-color: #cccccc;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-datepicker table tr td.calendar-decade span.inner{
|
||||
text-align: right;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:first-child{
|
||||
text-align: left;
|
||||
padding-left: 0;
|
||||
padding-right: 25px;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:last-child{
|
||||
text-align: right;
|
||||
padding-left: 25px;
|
||||
padding-right: 0;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:first-child input[type="text"]{
|
||||
margin-left: -1px;
|
||||
margin-right: 0;
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
.tail-datetime-calendar.rtl .calendar-timepicker .timepicker-field:last-child input[type="text"]{
|
||||
margin-left: 0;
|
||||
margin-right: -1px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
/* @end RTL */
|
||||
|
||||
/*# sourceMappingURL=tail.datetime-default-green.map */
|
||||
755
frontend/vendor/flatpickr.css
vendored
755
frontend/vendor/flatpickr.css
vendored
@ -1,755 +0,0 @@
|
||||
/*
|
||||
custom code
|
||||
hides the up/down arrows in time (number) inputs
|
||||
*/
|
||||
/* webkit */
|
||||
.flatpickr-calendar input[type=number]::-webkit-inner-spin-button,
|
||||
.flatpickr-calendar input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
/* firefox */
|
||||
.flatpickr-calendar input[type=number] {
|
||||
-moz-appearance:textfield;
|
||||
}
|
||||
/* vendor code */
|
||||
.flatpickr-calendar {
|
||||
background: transparent;
|
||||
opacity: 0;
|
||||
display: none;
|
||||
text-align: center;
|
||||
visibility: hidden;
|
||||
padding: 0;
|
||||
-webkit-animation: none;
|
||||
animation: none;
|
||||
direction: ltr;
|
||||
border: 0;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
width: 307.875px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
background: #fff;
|
||||
-webkit-box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);
|
||||
box-shadow: 1px 0 0 #e6e6e6, -1px 0 0 #e6e6e6, 0 1px 0 #e6e6e6, 0 -1px 0 #e6e6e6, 0 3px 13px rgba(0,0,0,0.08);
|
||||
}
|
||||
.flatpickr-calendar.open,
|
||||
.flatpickr-calendar.inline {
|
||||
opacity: 1;
|
||||
max-height: 640px;
|
||||
visibility: visible;
|
||||
}
|
||||
.flatpickr-calendar.open {
|
||||
display: inline-block;
|
||||
z-index: 99999;
|
||||
}
|
||||
.flatpickr-calendar.animate.open {
|
||||
-webkit-animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||
animation: fpFadeInDown 300ms cubic-bezier(0.23, 1, 0.32, 1);
|
||||
}
|
||||
.flatpickr-calendar.inline {
|
||||
display: block;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.flatpickr-calendar.static {
|
||||
position: absolute;
|
||||
top: calc(100% + 2px);
|
||||
}
|
||||
.flatpickr-calendar.static.open {
|
||||
z-index: 999;
|
||||
display: block;
|
||||
}
|
||||
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+1) .flatpickr-day.inRange:nth-child(7n+7) {
|
||||
-webkit-box-shadow: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.flatpickr-calendar.multiMonth .flatpickr-days .dayContainer:nth-child(n+2) .flatpickr-day.inRange:nth-child(7n+1) {
|
||||
-webkit-box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||
box-shadow: -2px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||
}
|
||||
.flatpickr-calendar .hasWeeks .dayContainer,
|
||||
.flatpickr-calendar .hasTime .dayContainer {
|
||||
border-bottom: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
.flatpickr-calendar .hasWeeks .dayContainer {
|
||||
border-left: 0;
|
||||
}
|
||||
.flatpickr-calendar.showTimeInput.hasTime .flatpickr-time {
|
||||
height: 40px;
|
||||
border-top: 1px solid #e6e6e6;
|
||||
}
|
||||
.flatpickr-calendar.noCalendar.hasTime .flatpickr-time {
|
||||
height: auto;
|
||||
}
|
||||
.flatpickr-calendar:before,
|
||||
.flatpickr-calendar:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
border: solid transparent;
|
||||
content: '';
|
||||
height: 0;
|
||||
width: 0;
|
||||
left: 22px;
|
||||
}
|
||||
.flatpickr-calendar.rightMost:before,
|
||||
.flatpickr-calendar.rightMost:after {
|
||||
left: auto;
|
||||
right: 22px;
|
||||
}
|
||||
.flatpickr-calendar:before {
|
||||
border-width: 5px;
|
||||
margin: 0 -5px;
|
||||
}
|
||||
.flatpickr-calendar:after {
|
||||
border-width: 4px;
|
||||
margin: 0 -4px;
|
||||
}
|
||||
.flatpickr-calendar.arrowTop:before,
|
||||
.flatpickr-calendar.arrowTop:after {
|
||||
bottom: 100%;
|
||||
}
|
||||
.flatpickr-calendar.arrowTop:before {
|
||||
border-bottom-color: #e6e6e6;
|
||||
}
|
||||
.flatpickr-calendar.arrowTop:after {
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.flatpickr-calendar.arrowBottom:before,
|
||||
.flatpickr-calendar.arrowBottom:after {
|
||||
top: 100%;
|
||||
}
|
||||
.flatpickr-calendar.arrowBottom:before {
|
||||
border-top-color: #e6e6e6;
|
||||
}
|
||||
.flatpickr-calendar.arrowBottom:after {
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.flatpickr-calendar:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.flatpickr-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.flatpickr-months {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
.flatpickr-months .flatpickr-month {
|
||||
background: transparent;
|
||||
color: rgba(0,0,0,0.9);
|
||||
fill: rgba(0,0,0,0.9);
|
||||
height: 28px;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
overflow: hidden;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month,
|
||||
.flatpickr-months .flatpickr-next-month {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
line-height: 16px;
|
||||
height: 28px;
|
||||
padding: 10px;
|
||||
z-index: 3;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month.disabled,
|
||||
.flatpickr-months .flatpickr-next-month.disabled {
|
||||
display: none;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month i,
|
||||
.flatpickr-months .flatpickr-next-month i {
|
||||
position: relative;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month.flatpickr-prev-month,
|
||||
.flatpickr-months .flatpickr-next-month.flatpickr-prev-month {
|
||||
/*
|
||||
/*rtl:begin:ignore*/
|
||||
/*
|
||||
*/
|
||||
left: 0;
|
||||
/*
|
||||
/*rtl:end:ignore*/
|
||||
/*
|
||||
*/
|
||||
}
|
||||
/*
|
||||
/*rtl:begin:ignore*/
|
||||
/*
|
||||
/*rtl:end:ignore*/
|
||||
.flatpickr-months .flatpickr-prev-month.flatpickr-next-month,
|
||||
.flatpickr-months .flatpickr-next-month.flatpickr-next-month {
|
||||
/*
|
||||
/*rtl:begin:ignore*/
|
||||
/*
|
||||
*/
|
||||
right: 0;
|
||||
/*
|
||||
/*rtl:end:ignore*/
|
||||
/*
|
||||
*/
|
||||
}
|
||||
/*
|
||||
/*rtl:begin:ignore*/
|
||||
/*
|
||||
/*rtl:end:ignore*/
|
||||
.flatpickr-months .flatpickr-prev-month:hover,
|
||||
.flatpickr-months .flatpickr-next-month:hover {
|
||||
color: #959ea9;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month:hover svg,
|
||||
.flatpickr-months .flatpickr-next-month:hover svg {
|
||||
fill: #f64747;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month svg,
|
||||
.flatpickr-months .flatpickr-next-month svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
.flatpickr-months .flatpickr-prev-month svg path,
|
||||
.flatpickr-months .flatpickr-next-month svg path {
|
||||
-webkit-transition: fill 0.1s;
|
||||
transition: fill 0.1s;
|
||||
fill: inherit;
|
||||
}
|
||||
.numInputWrapper {
|
||||
position: relative;
|
||||
height: auto;
|
||||
}
|
||||
.numInputWrapper input,
|
||||
.numInputWrapper span {
|
||||
display: inline-block;
|
||||
}
|
||||
.numInputWrapper input {
|
||||
width: 100%;
|
||||
min-width: auto !important;
|
||||
}
|
||||
.numInputWrapper input::-ms-clear {
|
||||
display: none;
|
||||
}
|
||||
.numInputWrapper span {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 14px;
|
||||
padding: 0 4px 0 2px;
|
||||
height: 50%;
|
||||
line-height: 50%;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
border: 1px solid rgba(57,57,57,0.15);
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.numInputWrapper span:hover {
|
||||
background: rgba(0,0,0,0.1);
|
||||
}
|
||||
.numInputWrapper span:active {
|
||||
background: rgba(0,0,0,0.2);
|
||||
}
|
||||
.numInputWrapper span:after {
|
||||
display: block;
|
||||
content: '';
|
||||
position: absolute;
|
||||
}
|
||||
.numInputWrapper span.arrowUp {
|
||||
top: 0;
|
||||
border-bottom: 0;
|
||||
}
|
||||
.numInputWrapper span.arrowUp:after {
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid rgba(57,57,57,0.6);
|
||||
top: 26%;
|
||||
}
|
||||
.numInputWrapper span.arrowDown {
|
||||
top: 50%;
|
||||
}
|
||||
.numInputWrapper span.arrowDown:after {
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 4px solid rgba(57,57,57,0.6);
|
||||
top: 40%;
|
||||
}
|
||||
.numInputWrapper span svg {
|
||||
width: inherit;
|
||||
height: auto;
|
||||
}
|
||||
.numInputWrapper span svg path {
|
||||
fill: rgba(0,0,0,0.5);
|
||||
}
|
||||
.numInputWrapper:hover {
|
||||
background: rgba(0,0,0,0.05);
|
||||
}
|
||||
.numInputWrapper:hover span {
|
||||
opacity: 1;
|
||||
}
|
||||
.flatpickr-current-month {
|
||||
font-size: 135%;
|
||||
line-height: inherit;
|
||||
font-weight: 300;
|
||||
color: inherit;
|
||||
position: absolute;
|
||||
width: 75%;
|
||||
left: 12.5%;
|
||||
padding: 6.16px 0 0 0;
|
||||
line-height: 1;
|
||||
height: 28px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
-webkit-transform: translate3d(0px, 0px, 0px);
|
||||
transform: translate3d(0px, 0px, 0px);
|
||||
}
|
||||
.flatpickr-current-month span.cur-month {
|
||||
font-family: inherit;
|
||||
font-weight: 700;
|
||||
color: inherit;
|
||||
display: inline-block;
|
||||
margin-left: 0.5ch;
|
||||
padding: 0;
|
||||
}
|
||||
.flatpickr-current-month span.cur-month:hover {
|
||||
background: rgba(0,0,0,0.05);
|
||||
}
|
||||
.flatpickr-current-month .numInputWrapper {
|
||||
width: 6ch;
|
||||
width: 7ch\0;
|
||||
display: inline-block;
|
||||
}
|
||||
.flatpickr-current-month .numInputWrapper span.arrowUp:after {
|
||||
border-bottom-color: rgba(0,0,0,0.9);
|
||||
}
|
||||
.flatpickr-current-month .numInputWrapper span.arrowDown:after {
|
||||
border-top-color: rgba(0,0,0,0.9);
|
||||
}
|
||||
.flatpickr-current-month input.cur-year {
|
||||
background: transparent;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
cursor: text;
|
||||
padding: 0 0 0 0.5ch;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: 300;
|
||||
line-height: inherit;
|
||||
height: auto;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
vertical-align: initial;
|
||||
}
|
||||
.flatpickr-current-month input.cur-year:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.flatpickr-current-month input.cur-year[disabled],
|
||||
.flatpickr-current-month input.cur-year[disabled]:hover {
|
||||
font-size: 100%;
|
||||
color: rgba(0,0,0,0.5);
|
||||
background: transparent;
|
||||
pointer-events: none;
|
||||
}
|
||||
.flatpickr-weekdays {
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
}
|
||||
.flatpickr-weekdays .flatpickr-weekdaycontainer {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
}
|
||||
span.flatpickr-weekday {
|
||||
cursor: default;
|
||||
font-size: 90%;
|
||||
background: transparent;
|
||||
color: rgba(0,0,0,0.54);
|
||||
line-height: 1;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
display: block;
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
font-weight: bolder;
|
||||
}
|
||||
.dayContainer,
|
||||
.flatpickr-weeks {
|
||||
padding: 1px 0 0 0;
|
||||
}
|
||||
.flatpickr-days {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: start;
|
||||
-webkit-align-items: flex-start;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
width: 307.875px;
|
||||
}
|
||||
.flatpickr-days:focus {
|
||||
outline: 0;
|
||||
}
|
||||
.dayContainer {
|
||||
padding: 0;
|
||||
outline: 0;
|
||||
text-align: left;
|
||||
width: 307.875px;
|
||||
min-width: 307.875px;
|
||||
max-width: 307.875px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
display: -ms-flexbox;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
-ms-flex-pack: justify;
|
||||
-webkit-justify-content: space-around;
|
||||
justify-content: space-around;
|
||||
-webkit-transform: translate3d(0px, 0px, 0px);
|
||||
transform: translate3d(0px, 0px, 0px);
|
||||
opacity: 1;
|
||||
}
|
||||
.dayContainer + .dayContainer {
|
||||
-webkit-box-shadow: -1px 0 0 #e6e6e6;
|
||||
box-shadow: -1px 0 0 #e6e6e6;
|
||||
}
|
||||
.flatpickr-day {
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 150px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
color: #393939;
|
||||
cursor: pointer;
|
||||
font-weight: 400;
|
||||
width: 14.2857143%;
|
||||
-webkit-flex-basis: 14.2857143%;
|
||||
-ms-flex-preferred-size: 14.2857143%;
|
||||
flex-basis: 14.2857143%;
|
||||
max-width: 39px;
|
||||
height: 39px;
|
||||
line-height: 39px;
|
||||
margin: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
-webkit-box-pack: center;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
}
|
||||
.flatpickr-day.inRange,
|
||||
.flatpickr-day.prevMonthDay.inRange,
|
||||
.flatpickr-day.nextMonthDay.inRange,
|
||||
.flatpickr-day.today.inRange,
|
||||
.flatpickr-day.prevMonthDay.today.inRange,
|
||||
.flatpickr-day.nextMonthDay.today.inRange,
|
||||
.flatpickr-day:hover,
|
||||
.flatpickr-day.prevMonthDay:hover,
|
||||
.flatpickr-day.nextMonthDay:hover,
|
||||
.flatpickr-day:focus,
|
||||
.flatpickr-day.prevMonthDay:focus,
|
||||
.flatpickr-day.nextMonthDay:focus {
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
background: #e6e6e6;
|
||||
border-color: #e6e6e6;
|
||||
}
|
||||
.flatpickr-day.today {
|
||||
border-color: #959ea9;
|
||||
}
|
||||
.flatpickr-day.today:hover,
|
||||
.flatpickr-day.today:focus {
|
||||
border-color: #959ea9;
|
||||
background: #959ea9;
|
||||
color: #fff;
|
||||
}
|
||||
.flatpickr-day.selected,
|
||||
.flatpickr-day.startRange,
|
||||
.flatpickr-day.endRange,
|
||||
.flatpickr-day.selected.inRange,
|
||||
.flatpickr-day.startRange.inRange,
|
||||
.flatpickr-day.endRange.inRange,
|
||||
.flatpickr-day.selected:focus,
|
||||
.flatpickr-day.startRange:focus,
|
||||
.flatpickr-day.endRange:focus,
|
||||
.flatpickr-day.selected:hover,
|
||||
.flatpickr-day.startRange:hover,
|
||||
.flatpickr-day.endRange:hover,
|
||||
.flatpickr-day.selected.prevMonthDay,
|
||||
.flatpickr-day.startRange.prevMonthDay,
|
||||
.flatpickr-day.endRange.prevMonthDay,
|
||||
.flatpickr-day.selected.nextMonthDay,
|
||||
.flatpickr-day.startRange.nextMonthDay,
|
||||
.flatpickr-day.endRange.nextMonthDay {
|
||||
background: #569ff7;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
color: #fff;
|
||||
border-color: #569ff7;
|
||||
}
|
||||
.flatpickr-day.selected.startRange,
|
||||
.flatpickr-day.startRange.startRange,
|
||||
.flatpickr-day.endRange.startRange {
|
||||
border-radius: 50px 0 0 50px;
|
||||
}
|
||||
.flatpickr-day.selected.endRange,
|
||||
.flatpickr-day.startRange.endRange,
|
||||
.flatpickr-day.endRange.endRange {
|
||||
border-radius: 0 50px 50px 0;
|
||||
}
|
||||
.flatpickr-day.selected.startRange + .endRange,
|
||||
.flatpickr-day.startRange.startRange + .endRange,
|
||||
.flatpickr-day.endRange.startRange + .endRange {
|
||||
-webkit-box-shadow: -10px 0 0 #569ff7;
|
||||
box-shadow: -10px 0 0 #569ff7;
|
||||
}
|
||||
.flatpickr-day.selected.startRange.endRange,
|
||||
.flatpickr-day.startRange.startRange.endRange,
|
||||
.flatpickr-day.endRange.startRange.endRange {
|
||||
border-radius: 50px;
|
||||
}
|
||||
.flatpickr-day.inRange {
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||
box-shadow: -5px 0 0 #e6e6e6, 5px 0 0 #e6e6e6;
|
||||
}
|
||||
.flatpickr-day.disabled,
|
||||
.flatpickr-day.disabled:hover,
|
||||
.flatpickr-day.prevMonthDay,
|
||||
.flatpickr-day.nextMonthDay,
|
||||
.flatpickr-day.notAllowed,
|
||||
.flatpickr-day.notAllowed.prevMonthDay,
|
||||
.flatpickr-day.notAllowed.nextMonthDay {
|
||||
color: rgba(57,57,57,0.3);
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
.flatpickr-day.disabled,
|
||||
.flatpickr-day.disabled:hover {
|
||||
cursor: not-allowed;
|
||||
color: rgba(57,57,57,0.1);
|
||||
}
|
||||
.flatpickr-day.week.selected {
|
||||
border-radius: 0;
|
||||
-webkit-box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;
|
||||
box-shadow: -5px 0 0 #569ff7, 5px 0 0 #569ff7;
|
||||
}
|
||||
.flatpickr-day.hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.rangeMode .flatpickr-day {
|
||||
margin-top: 1px;
|
||||
}
|
||||
.flatpickr-weekwrapper {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
.flatpickr-weekwrapper .flatpickr-weeks {
|
||||
padding: 0 12px;
|
||||
-webkit-box-shadow: 1px 0 0 #e6e6e6;
|
||||
box-shadow: 1px 0 0 #e6e6e6;
|
||||
}
|
||||
.flatpickr-weekwrapper .flatpickr-weekday {
|
||||
float: none;
|
||||
width: 100%;
|
||||
line-height: 28px;
|
||||
}
|
||||
.flatpickr-weekwrapper span.flatpickr-day,
|
||||
.flatpickr-weekwrapper span.flatpickr-day:hover {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
color: rgba(57,57,57,0.3);
|
||||
background: transparent;
|
||||
cursor: default;
|
||||
border: none;
|
||||
}
|
||||
.flatpickr-innerContainer {
|
||||
display: block;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
.flatpickr-rContainer {
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.flatpickr-time {
|
||||
text-align: center;
|
||||
outline: 0;
|
||||
display: block;
|
||||
height: 0;
|
||||
line-height: 40px;
|
||||
max-height: 40px;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
}
|
||||
.flatpickr-time:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.flatpickr-time .numInputWrapper {
|
||||
-webkit-box-flex: 1;
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
width: 40%;
|
||||
height: 40px;
|
||||
float: left;
|
||||
}
|
||||
.flatpickr-time .numInputWrapper span.arrowUp:after {
|
||||
border-bottom-color: #393939;
|
||||
}
|
||||
.flatpickr-time .numInputWrapper span.arrowDown:after {
|
||||
border-top-color: #393939;
|
||||
}
|
||||
.flatpickr-time.hasSeconds .numInputWrapper {
|
||||
width: 26%;
|
||||
}
|
||||
.flatpickr-time.time24hr .numInputWrapper {
|
||||
width: 49%;
|
||||
}
|
||||
.flatpickr-time input {
|
||||
background: transparent;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: inherit;
|
||||
line-height: inherit;
|
||||
cursor: pointer;
|
||||
color: #393939;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.flatpickr-time input.flatpickr-hour {
|
||||
font-weight: bold;
|
||||
}
|
||||
.flatpickr-time input.flatpickr-minute,
|
||||
.flatpickr-time input.flatpickr-second {
|
||||
font-weight: 400;
|
||||
}
|
||||
.flatpickr-time input:focus {
|
||||
outline: 0;
|
||||
border: 0;
|
||||
}
|
||||
.flatpickr-time .flatpickr-time-separator,
|
||||
.flatpickr-time .flatpickr-am-pm {
|
||||
height: inherit;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
line-height: inherit;
|
||||
color: #393939;
|
||||
font-weight: bold;
|
||||
width: 2%;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-align-self: center;
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
}
|
||||
.flatpickr-time .flatpickr-am-pm {
|
||||
outline: 0;
|
||||
width: 18%;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
}
|
||||
.flatpickr-time .flatpickr-am-pm:hover,
|
||||
.flatpickr-time .flatpickr-am-pm:focus {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.flatpickr-input[readonly] {
|
||||
cursor: pointer;
|
||||
min-width: auto;
|
||||
}
|
||||
@-webkit-keyframes fpFadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, -20px, 0);
|
||||
transform: translate3d(0, -20px, 0);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
@keyframes fpFadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, -20px, 0);
|
||||
transform: translate3d(0, -20px, 0);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
2
frontend/vendor/main.js
vendored
2
frontend/vendor/main.js
vendored
@ -1,2 +1,2 @@
|
||||
import './fontawesome.css';
|
||||
import './flatpickr.css';
|
||||
import './datetime.css';
|
||||
5
jsconfig.json
Normal file
5
jsconfig.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
}
|
||||
1823
package-lock.json
generated
1823
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@ -49,16 +49,17 @@
|
||||
"defaults"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.4.4",
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/cli": "^7.5.5",
|
||||
"@babel/core": "^7.5.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
||||
"@babel/plugin-proposal-decorators": "^7.4.4",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/plugin-transform-runtime": "^7.5.5",
|
||||
"@babel/preset-env": "^7.5.5",
|
||||
"@commitlint/cli": "^8.1.0",
|
||||
"@commitlint/config-conventional": "^8.0.0",
|
||||
"autoprefixer": "^9.6.0",
|
||||
"@commitlint/config-conventional": "^8.1.0",
|
||||
"autoprefixer": "^9.6.1",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.5",
|
||||
@ -66,9 +67,9 @@
|
||||
"css-loader": "^2.1.1",
|
||||
"eslint": "^5.16.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"husky": "^2.4.1",
|
||||
"husky": "^2.7.0",
|
||||
"jasmine-core": "^3.4.0",
|
||||
"karma": "^4.1.0",
|
||||
"karma": "^4.3.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-cli": "^2.0.0",
|
||||
"karma-jasmine": "^2.0.1",
|
||||
@ -81,15 +82,19 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"null-loader": "^2.0.0",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sass-loader": "^7.3.1",
|
||||
"standard-version": "^6.0.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"uglifyjs-webpack-plugin": "^2.1.3",
|
||||
"webpack": "^4.34.0",
|
||||
"webpack-cli": "^3.3.4"
|
||||
"uglifyjs-webpack-plugin": "^2.2.0",
|
||||
"webpack": "^4.39.3",
|
||||
"webpack-cli": "^3.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"flatpickr": "^4.5.7",
|
||||
"npm": "^6.10.1"
|
||||
"@babel/runtime": "^7.5.5",
|
||||
"moment": "^2.24.0",
|
||||
"npm": "^6.11.2",
|
||||
"tail.datetime": "git+https://github.com/uni2work/tail.DateTime.git#master",
|
||||
"core-js": "^3.2.1",
|
||||
"whatwg-fetch": "^3.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,6 +734,20 @@ tagAccessPredicate AuthTutor = APDB $ \mAuthId route _ -> exceptT return return
|
||||
guardMExceptT (not $ Map.null resMap) (unauthorizedI MsgUnauthorizedTutor)
|
||||
return Authorized
|
||||
tagAccessPredicate AuthTime = APDB $ \mAuthId route _ -> case route of
|
||||
CApplicationR tid ssh csh _ _ -> maybeT (unauthorizedI MsgUnauthorizedApplicationTime) $ do
|
||||
course <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh
|
||||
allocationCourse <- $cachedHereBinary course . lift . getBy $ UniqueAllocationCourse course
|
||||
allocation <- for allocationCourse $ \(Entity _ AllocationCourse{..}) -> $cachedHereBinary allocationCourseAllocation . MaybeT $ get allocationCourseAllocation
|
||||
|
||||
case allocation of
|
||||
Nothing -> return ()
|
||||
Just Allocation{..} -> do
|
||||
cTime <- liftIO getCurrentTime
|
||||
guard $ NTop allocationStaffAllocationFrom <= NTop (Just cTime)
|
||||
guard $ NTop (Just cTime) <= NTop allocationStaffAllocationTo
|
||||
|
||||
return Authorized
|
||||
|
||||
CExamR tid ssh csh examn subRoute -> maybeT (unauthorizedI MsgUnauthorizedExamTime) $ do
|
||||
course <- $cachedHereBinary (tid, ssh, csh) . MaybeT . getKeyBy $ TermSchoolCourseShort tid ssh csh
|
||||
Entity eId Exam{..} <- $cachedHereBinary (course, examn) . MaybeT . getBy $ UniqueExam course examn
|
||||
@ -1679,7 +1693,6 @@ siteLayout' headingOverride widget = do
|
||||
addStylesheet $ StaticR bundles_css_vendor_css
|
||||
addStylesheet $ StaticR bundles_css_main_css
|
||||
-- JavaScript
|
||||
addScript $ StaticR bundles_js_polyfills_js
|
||||
addScript $ StaticR bundles_js_vendor_js
|
||||
addScript $ StaticR bundles_js_main_js
|
||||
toWidget $(juliusFile "templates/i18n.julius")
|
||||
|
||||
@ -162,8 +162,8 @@ examOccurrenceForm prev = wFormToAForm $ do
|
||||
(eofNameRes, eofNameView) <- mpreq ciField ("" & addName (nudge "name")) (eofName <$> mPrev)
|
||||
(eofRoomRes, eofRoomView) <- mpreq textField ("" & addName (nudge "room")) (eofRoom <$> mPrev)
|
||||
(eofCapacityRes, eofCapacityView) <- mpreq (natFieldI MsgExamRoomCapacityNegative) ("" & addName (nudge "capacity")) (eofCapacity <$> mPrev)
|
||||
(eofStartRes, eofStartView) <- mpreq utcTimeField ("" & addName (nudge "start")) (eofStart <$> mPrev)
|
||||
(eofEndRes, eofEndView) <- mopt utcTimeField ("" & addName (nudge "end")) (eofEnd <$> mPrev)
|
||||
(eofStartRes, eofStartView) <- mpreq utcTimeField ("" & addName (nudge "start") & addDatepickerPositionAttr DPBottom) (eofStart <$> mPrev)
|
||||
(eofEndRes, eofEndView) <- mopt utcTimeField ("" & addName (nudge "end") & addDatepickerPositionAttr DPBottom) (eofEnd <$> mPrev)
|
||||
(eofDescRes, eofDescView) <- mopt htmlFieldSmall ("" & addName (nudge "description")) (eofDescription <$> mPrev)
|
||||
|
||||
return ( ExamOccurrenceForm
|
||||
|
||||
@ -848,7 +848,7 @@ localTimeField = Field
|
||||
where
|
||||
fieldTimeFormat :: String
|
||||
--fieldTimeFormat = "%e.%m.%y %k:%M"
|
||||
fieldTimeFormat = "%Y-%m-%dT%H:%M"
|
||||
fieldTimeFormat = "%Y-%m-%dT%H:%M:%S"
|
||||
|
||||
-- `defaultTimeLocale` is okay here, since `fieldTimeFormat` does not contain any
|
||||
readTime :: Text -> Either UniWorXMessage LocalTime
|
||||
|
||||
@ -108,6 +108,16 @@ addAttrs attr valus fs = fs { fsAttrs = insertAttr attr valu $ fsAttrs fs }
|
||||
where
|
||||
valu = T.intercalate " " valus
|
||||
|
||||
data DatepickerPosition = DPLeft | DPRight | DPTop | DPBottom deriving (Eq,Ord,Enum,Bounded,Read,Show)
|
||||
|
||||
instance Universe DatepickerPosition
|
||||
instance Finite DatepickerPosition
|
||||
|
||||
nullaryPathPiece ''DatepickerPosition $ camelToPathPiece' 1
|
||||
|
||||
addDatepickerPositionAttr :: DatepickerPosition -> FieldSettings site -> FieldSettings site
|
||||
addDatepickerPositionAttr = addAttr "data-datepicker-position" . toPathPiece
|
||||
|
||||
addPlaceholder :: Text -> FieldSettings site -> FieldSettings site
|
||||
addPlaceholder placeholder fs = fs { fsAttrs = (placeholderAttr, placeholder) : filter ((/= placeholderAttr) . fst) (fsAttrs fs) }
|
||||
where
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
if (window.App) {
|
||||
window.App.i18n.addMany(#{frontendI18n});
|
||||
// window.App.i18n.setLang(lang); TODO: set language string for datepicker config
|
||||
} else {
|
||||
throw new Error('I18n JavaScript service is missing!');
|
||||
}
|
||||
|
||||
@ -38,13 +38,22 @@ module.exports = {
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
modules: false
|
||||
modules: false,
|
||||
targets: {
|
||||
edge: "17",
|
||||
firefox: "50",
|
||||
chrome: "60",
|
||||
safari: "11.1",
|
||||
ie: "11",
|
||||
},
|
||||
useBuiltIns: "usage",
|
||||
corejs: 3
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
|
||||
test: /\.js$/
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
@ -71,9 +80,6 @@ module.exports = {
|
||||
vendor: [
|
||||
path.resolve(__dirname, 'frontend/vendor', 'main.js'),
|
||||
],
|
||||
polyfills: [
|
||||
path.resolve(__dirname, 'frontend/polyfills', 'main.js'),
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
|
||||
Loading…
Reference in New Issue
Block a user