mirror of https://github.com/nextcloud/calendar
Create sub components for editor, allow to save this or all future
Signed-off-by: Georg Ehrke <developer@georgehrke.com>
This commit is contained in:
parent
2f5e99f66c
commit
3a58916e0b
|
@ -347,3 +347,10 @@ button.delete:focus {
|
|||
max-width: 0 !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#app-sidebar .app-sidebar-header__action {
|
||||
max-height: none !important;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,10 @@
|
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
@include icon-black-white('briefcase', 'calendar', 2);
|
||||
@include icon-black-white('color-picker', 'calendar', 1);
|
||||
@include icon-black-white('embed', 'calendar', 1);
|
||||
@include icon-black-white('eye', 'calendar', 3);
|
||||
@include icon-black-white('leftarrow', 'calendar', 1);
|
||||
@include icon-black-white('random', 'calendar', 1);
|
||||
@include icon-black-white('reminder', 'calendar', 1);
|
||||
|
|
|
@ -1,5 +1,15 @@
|
|||
# Licenses
|
||||
|
||||
## briefcase.svg
|
||||
- Created by: [Oriza Creative](https://thenounproject.com/orizacreativa)
|
||||
- License: CC-BY
|
||||
- Link: https://thenounproject.com/search/?q=briefcase&i=2834945
|
||||
|
||||
## eye.svg
|
||||
- Created by: [David](https://thenounproject.com/kaxgyatso)
|
||||
- License: CC-BY
|
||||
- Link: https://thenounproject.com/search/?q=eye&i=428971
|
||||
|
||||
## repeat.svg
|
||||
- Created by: [Brandy Bora](https://thenounproject.com/brandy.bora/)
|
||||
- License: CC-BY
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:serif="http://www.serif.com/" viewBox="0 0 65 65" version="1.1" xml:space="preserve" style="" x="0px" y="0px" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2"><rect serif:id="carrer suitcase sales" x="0.749" y="0.952" width="64" height="64" style="" fill="none"></rect><path d="M51.737,36.95c-4.999,0.038 -9.999,0.06 -14.998,0.068l0,4.887c-0.006,0.193 -0.021,0.225 -0.049,0.309c-0.13,0.401 -0.434,0.674 -0.95,0.691l-5.998,0c-0.205,-0.007 -0.261,-0.028 -0.368,-0.071c-0.372,-0.147 -0.616,-0.431 -0.631,-0.929l0,-4.887c-5,-0.008 -9.999,-0.03 -14.998,-0.068l0,19.975c12.661,0.105 25.323,0.105 37.984,0l0.008,-19.975Zm-44.007,-0.159c-0.018,5.716 -0.037,11.432 0.018,17.148c0.024,1.547 1.361,2.934 2.959,2.959c0.346,0.004 0.693,0.007 1.039,0.01l0,-19.974c-1.021,-0.008 -2.042,-0.018 -3.063,-0.027c-0.323,-0.005 -0.642,-0.045 -0.953,-0.116Zm49.996,0.007c-0.303,0.066 -0.615,0.104 -0.935,0.109c-1.018,0.009 -2.037,0.018 -3.055,0.027l-0.008,19.974c0.346,-0.003 0.692,-0.006 1.039,-0.01c1.546,-0.024 2.944,-1.355 2.959,-2.979l0,-17.121Zm-26.984,-3.889l0,7.996l3.998,0l0,-7.996l-3.998,0Zm28.983,-17.993l-53.977,0c0,5.678 -0.053,11.355 0.001,17.032c0.024,1.554 1.36,2.934 2.959,2.96c1.276,0.012 2.552,0.023 3.828,0.033c0.096,-0.023 0.197,-0.034 0.302,-0.029c0.052,0.007 0.103,0.018 0.152,0.033c5.251,0.041 10.502,0.066 15.753,0.074l0,-3.11c0.006,-0.193 0.021,-0.225 0.049,-0.309c0.13,-0.401 0.434,-0.674 0.95,-0.69l5.998,0c0.021,0 0.041,0.001 0.062,0.002c0.193,0.018 0.223,0.035 0.306,0.068c0.372,0.147 0.616,0.431 0.631,0.929l0,3.11c5.257,-0.008 10.513,-0.033 15.769,-0.074c0.101,-0.026 0.209,-0.038 0.321,-0.033c0.047,0.007 0.093,0.016 0.138,0.029c1.266,-0.01 2.532,-0.021 3.799,-0.033c1.547,-0.025 2.944,-1.355 2.959,-2.979c0,0 0,-17.013 0,-17.013Z" style="" fill-rule="nonzero"></path><path d="M23.741,12.917l0,-3.002c0.01,-1.553 1.343,-2.964 2.96,-2.995c4.024,-0.025 8.048,-0.025 12.072,0c1.553,0.03 2.95,1.367 2.96,2.995l0,3.002l-17.992,0Zm15.993,0c0,-1.008 0.019,-2.017 0,-3.025c-0.017,-0.509 -0.462,-0.956 -0.973,-0.973c-4.006,-0.076 -8.012,0 -12.018,0c-0.531,0.003 -1,0.457 -1.003,1.003l0,2.995l13.994,0Z" style="" fill-rule="nonzero"></path></svg>
|
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"><circle cx="50" cy="50" r="12.272"></circle><path d="M50,21.363C25.454,21.363,5,47.954,5,50c0,2.044,20.454,28.637,45,28.637c24.545,0,45-26.591,45-28.637 C95,47.953,74.546,21.363,50,21.363z M50,70.454c-11.3,0-20.454-9.156-20.454-20.454c0-11.301,9.154-20.454,20.454-20.454 c11.299,0,20.454,9.153,20.454,20.454C70.454,61.298,61.299,70.454,50,70.454z"></path></svg>
|
After Width: | Height: | Size: 579 B |
|
@ -2658,6 +2658,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"autosize": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/autosize/-/autosize-4.0.2.tgz",
|
||||
"integrity": "sha512-jnSyH2d+qdfPGpWlcuhGiHmqBJ6g3X+8T+iRwFrHPLVcdoGJE/x6Qicm6aDHfTsbgZKxyV8UU/YB2p4cjKDRRA=="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
|
@ -4189,7 +4194,7 @@
|
|||
}
|
||||
},
|
||||
"calendar-js": {
|
||||
"version": "git+https://github.com/georgehrke/calendar-js.git#69d5d23d8bce3f7be13865c4a98419474e99c806",
|
||||
"version": "git+https://github.com/georgehrke/calendar-js.git#8dfe9b41f7160656518d1e242cf7333cf486d9f0",
|
||||
"from": "git+https://github.com/georgehrke/calendar-js.git",
|
||||
"requires": {
|
||||
"ical.js": "^1.3.0",
|
||||
|
@ -15144,6 +15149,14 @@
|
|||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
|
||||
"integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
|
||||
},
|
||||
"v-autosize": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/v-autosize/-/v-autosize-1.0.3.tgz",
|
||||
"integrity": "sha512-hglWoI7tTNFi7GDvHotsID5zl15vyzU6Gzfs91WB9lowy7/N6nfZ3wQCDlf1DGxUwdRxvfOhr+Vnf6evr8QFDQ==",
|
||||
"requires": {
|
||||
"autosize": "^4.0.2"
|
||||
}
|
||||
},
|
||||
"v-tooltip": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.2.tgz",
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
"p-limit": "^2.2.1",
|
||||
"p-queue": "^6.1.1",
|
||||
"uuid": "^3.3.3",
|
||||
"v-autosize": "^1.0.3",
|
||||
"v-tooltip": "^2.0.2",
|
||||
"vue": "^2.6.10",
|
||||
"vue-click-outside": "^1.0.7",
|
||||
|
|
|
@ -1,4 +1,28 @@
|
|||
<template />
|
||||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
|
|
@ -1,4 +1,28 @@
|
|||
<template />
|
||||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
|
@ -0,0 +1,118 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="eventComponentLoaded" class="property-wrapper">
|
||||
<div class="property-icon" :class="icon" :title="readableName" />
|
||||
<div class="property-input">
|
||||
<multiselect v-model="value" :options="options" :searchable="false"
|
||||
:allow-empty="false" :title="readableName" track-by="value"
|
||||
label="label" @select="changeValue"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasInfo" v-tooltip="info" class="property-info icon-details" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PropertyMixin from '../../../mixins/PropertyMixin'
|
||||
|
||||
export default {
|
||||
name: 'PropertyText',
|
||||
mixins: [
|
||||
PropertyMixin
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
value: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
options() {
|
||||
return this.propModel.options
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
eventComponent() {
|
||||
this.initValue()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initValue()
|
||||
},
|
||||
methods: {
|
||||
changeValue(selectedOption) {
|
||||
if (!selectedOption) {
|
||||
return
|
||||
}
|
||||
|
||||
this.eventComponent[this.propModel.name] = selectedOption.value
|
||||
},
|
||||
initValue() {
|
||||
if (!this.eventComponent) {
|
||||
return
|
||||
}
|
||||
|
||||
const value = this.eventComponent[this.propModel.name] || this.propModel.defaultValue
|
||||
this.value = this.options.find((option) => option.value === value)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.property-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
min-height: 46px;
|
||||
}
|
||||
|
||||
.property-icon,
|
||||
.property-info {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.property-icon {
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.property-info {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.property-info:hover {
|
||||
opacity: 1
|
||||
}
|
||||
|
||||
.property-input {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
width: 100%;
|
||||
margin: 3px 3px 3px 0;
|
||||
}
|
||||
</style>
|
|
@ -1,11 +1,109 @@
|
|||
<template />
|
||||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="eventComponentLoaded" class="property-wrapper">
|
||||
<div class="property-icon" :class="icon" :title="readableName" />
|
||||
<div class="property-input">
|
||||
<textarea v-if="!isReadOnly" v-autosize :value="value"
|
||||
:placeholder="placeholder" :title="readableName" rows="1"
|
||||
@input="changeValue"
|
||||
/>
|
||||
<div v-if="isReadOnly">
|
||||
{{ value }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="hasInfo" v-tooltip="info" class="property-info icon-details" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import autosize from 'v-autosize'
|
||||
import PropertyMixin from '../../../mixins/PropertyMixin'
|
||||
|
||||
export default {
|
||||
name: 'PropertyTextVue'
|
||||
name: 'PropertyText',
|
||||
directives: {
|
||||
autosize
|
||||
},
|
||||
mixins: [
|
||||
PropertyMixin
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
value: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
eventComponent() {
|
||||
this.initValue()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initValue()
|
||||
},
|
||||
methods: {
|
||||
changeValue(event) {
|
||||
if (!this.eventComponentLoaded) {
|
||||
return
|
||||
}
|
||||
|
||||
this.eventComponent[this.propModel.name] = event.target.value
|
||||
},
|
||||
initValue() {
|
||||
if (!this.eventComponentLoaded) {
|
||||
return
|
||||
}
|
||||
|
||||
this.value = this.eventComponent[this.propModel.name]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.property-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.property-icon,
|
||||
.property-info {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.property-icon {
|
||||
margin-left: -5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.property-input {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,11 +1,91 @@
|
|||
<template />
|
||||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<div v-if="eventComponentLoaded" class="property-wrapper">
|
||||
<div class="property-input">
|
||||
<textarea v-if="!isReadOnly" v-autosize :value="value"
|
||||
:placeholder="placeholder" :title="readableName" rows="1"
|
||||
@input="changeValue"
|
||||
/>
|
||||
<div v-if="isReadOnly">
|
||||
{{ value }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import autosize from 'v-autosize'
|
||||
import PropertyMixin from '../../../mixins/PropertyMixin'
|
||||
|
||||
export default {
|
||||
name: 'PropertyTitle'
|
||||
name: 'PropertyTitle',
|
||||
directives: {
|
||||
autosize
|
||||
},
|
||||
mixins: [
|
||||
PropertyMixin
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
value: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
eventComponent() {
|
||||
this.initValue()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initValue()
|
||||
},
|
||||
methods: {
|
||||
changeValue(event) {
|
||||
if (!this.eventComponentLoaded) {
|
||||
return
|
||||
}
|
||||
|
||||
this.eventComponent[this.propModel.name] = event.target.value
|
||||
},
|
||||
initValue() {
|
||||
if (!this.eventComponentLoaded) {
|
||||
return
|
||||
}
|
||||
|
||||
this.value = this.eventComponent[this.propModel.name]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.property-wrapper,
|
||||
.property-input,
|
||||
textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
font-size: 20px
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -18,7 +18,7 @@ export default {
|
|||
props: {
|
||||
eventComponent: {
|
||||
type: Object,
|
||||
default: false
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
|
@ -29,18 +29,17 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
timeFormat() {
|
||||
// if (this.eventComponent.isAllDay) {
|
||||
if (true) {
|
||||
return 'YYYY-MM-DD'
|
||||
}
|
||||
// if (this.eventComponent.isAllDay()) {
|
||||
// return 'YYYY-MM-DD'
|
||||
// }
|
||||
|
||||
return 'YYYY-MM-DD HH:mm'
|
||||
},
|
||||
timeType() {
|
||||
// if (this.eventComponent.isAllDay) {
|
||||
if (true) {
|
||||
return 'date'
|
||||
}
|
||||
// if (true) {
|
||||
// return 'date'
|
||||
// }
|
||||
|
||||
return 'datetime'
|
||||
}
|
||||
|
|
|
@ -30,23 +30,23 @@ export default {
|
|||
props: {
|
||||
eventComponent: {
|
||||
type: Object,
|
||||
default: false
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
timeFormat() {
|
||||
// if (this.eventComponent.isAllDay) {
|
||||
if (true) {
|
||||
return 'YYYY-MM-DD'
|
||||
}
|
||||
// if (true) {
|
||||
// return 'YYYY-MM-DD'
|
||||
// }
|
||||
|
||||
return 'YYYY-MM-DD HH:mm'
|
||||
},
|
||||
timeType() {
|
||||
// if (this.eventComponent.isAllDay) {
|
||||
if (true) {
|
||||
return 'date'
|
||||
}
|
||||
// if (true) {
|
||||
// return 'date'
|
||||
// }
|
||||
|
||||
return 'datetime'
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* @copyright Copyright (c) 2018 Georg Ehrke
|
||||
*
|
||||
* @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
*
|
||||
* @license GNU AGPL version 3 or any later version
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
import EventComponent from 'calendar-js/src/components/root/eventComponent'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// This is coming from rfcProps
|
||||
propModel: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
eventComponent: {
|
||||
validator: prop => prop instanceof EventComponent || prop === null,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
icon() {
|
||||
return this.propModel.icon || ''
|
||||
},
|
||||
placeholder() {
|
||||
return this.propModel.placeholder || ''
|
||||
},
|
||||
info() {
|
||||
return this.propModel.info || ''
|
||||
},
|
||||
readableName() {
|
||||
return this.propModel.readableName || ''
|
||||
},
|
||||
hasInfo() {
|
||||
return this.propModel.info !== undefined
|
||||
},
|
||||
eventComponentLoaded() {
|
||||
return this.eventComponent !== null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,156 @@ import { getParserManager } from 'calendar-js'
|
|||
import DateTimeValue from 'calendar-js/src/values/dateTimeValue'
|
||||
import CalendarComponent from 'calendar-js/src/components/calendarComponent'
|
||||
|
||||
// export default function CalendarObject(calendarData, calendarId, dav = null) {
|
||||
// const context = {
|
||||
// dav,
|
||||
// updateQueue: new PQueue({ concurrency: 1 }),
|
||||
// vcalendar: null
|
||||
// }
|
||||
//
|
||||
// const iface = {
|
||||
// calendarId,
|
||||
// conflict: false,
|
||||
// }
|
||||
//
|
||||
// Object.defineProperties(iface, {
|
||||
// id: {
|
||||
// get() {
|
||||
// if (context.dav) {
|
||||
// return btoa(context.dav.url)
|
||||
// }
|
||||
//
|
||||
// return 'new'
|
||||
// }
|
||||
// },
|
||||
// uid: {
|
||||
// get() {
|
||||
// const iterator = context.vcalendar.getVObjectIterator()
|
||||
// const firstVObject = iterator.next().value
|
||||
// if (firstVObject) {
|
||||
// return firstVObject.uid
|
||||
// }
|
||||
//
|
||||
// return null
|
||||
// }
|
||||
// },
|
||||
// objectType: {
|
||||
// get() {
|
||||
// const iterator = context.vcalendar.getVObjectIterator()
|
||||
// const firstVObject = iterator.next().value
|
||||
// if (firstVObject) {
|
||||
// return firstVObject.name
|
||||
// }
|
||||
//
|
||||
// return null
|
||||
// }
|
||||
// },
|
||||
// dav: {
|
||||
// get() {
|
||||
// return context.dav
|
||||
// }
|
||||
// },
|
||||
// vcalendar: {
|
||||
// get() {
|
||||
// return context.vcalendar
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
//
|
||||
// /**
|
||||
// * Whether or not this calendar-object is an event
|
||||
// *
|
||||
// * @returns {boolean}
|
||||
// */
|
||||
// iface.isEvent = () => {
|
||||
// return iface.objectType === 'vevent'
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Whether or not this calendar-object is a task
|
||||
// *
|
||||
// * @returns {boolean}
|
||||
// */
|
||||
// iface.isTodo = () => {
|
||||
// return iface.objectType === 'vtodo'
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get all recurrence-items in given range
|
||||
// *
|
||||
// * @param {Date} start Begin of time-range
|
||||
// * @param {Date} end End of time-range
|
||||
// * @returns {Array}
|
||||
// */
|
||||
// iface.getAllObjectsInTimeRange = (start, end) => {
|
||||
// const iterator = context.vcalendar.getVObjectIterator()
|
||||
// const firstVObject = iterator.next().value
|
||||
// if (!firstVObject) {
|
||||
// return []
|
||||
// }
|
||||
//
|
||||
// const s = DateTimeValue.fromJSDate(start, true)
|
||||
// const e = DateTimeValue.fromJSDate(end, true)
|
||||
// return firstVObject.recurrenceManager.getAllOccurrencesBetween(s, e)
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Get recurrence-item at exactly a given recurrence-Id
|
||||
// *
|
||||
// * @param {Date} recurrenceId RecurrenceId to retrieve
|
||||
// * @returns {AbstractRecurringComponent|null}
|
||||
// */
|
||||
// iface.getObjectAtRecurrenceId = (recurrenceId) => {
|
||||
// const iterator = context.vcalendar.getVObjectIterator()
|
||||
// const firstVObject = iterator.next().value
|
||||
// if (!firstVObject) {
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// const d = DateTimeValue.fromJSDate(recurrenceId, true)
|
||||
// return firstVObject.recurrenceManager.getOccurrenceAtExactly(d)
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * resets the inter vcalendar to the dav data
|
||||
// *
|
||||
// * @param {CalendarComponent|String} data Data to reset to
|
||||
// */
|
||||
// iface.resetToDav = (data = null) => {
|
||||
// console.debug('RESET TO DAV CALLED ' + context.dav.url)
|
||||
// if (data instanceof CalendarComponent) {
|
||||
// context.vcalendar = data
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// if (data === null && context.dav === null) {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// const parserManager = getParserManager()
|
||||
// const parser = parserManager.getParserForFileType('text/calendar')
|
||||
//
|
||||
// const calendarData = data || context.dav.data
|
||||
// parser.parse(calendarData)
|
||||
//
|
||||
// const itemIterator = parser.getItemIterator()
|
||||
// const firstVCalendar = itemIterator.next().value
|
||||
// if (firstVCalendar) {
|
||||
// context.vcalendar = firstVCalendar
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// iface.existsOnServer = () => {
|
||||
// return !!context.dav
|
||||
// }
|
||||
//
|
||||
// iface.resetToDav()
|
||||
//
|
||||
// Object.freeze(iface)
|
||||
//
|
||||
// return iface
|
||||
// }
|
||||
|
||||
export default class CalendarObject {
|
||||
|
||||
/**
|
||||
|
@ -197,4 +347,13 @@ export default class CalendarObject {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this objects exists on the server
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
existsOnServer() {
|
||||
return !!this.dav
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,63 +20,85 @@
|
|||
*
|
||||
*/
|
||||
|
||||
export const properties = {
|
||||
export default {
|
||||
// RFC 5545
|
||||
class: {
|
||||
name: 'accessClass',
|
||||
readableName: t('calendar', 'When shared show'),
|
||||
icon: 'icon-share',
|
||||
options: {
|
||||
|
||||
},
|
||||
icon: 'icon-eye',
|
||||
options: [
|
||||
{ value: 'PUBLIC', label: t('calendar', 'When shared show full event') },
|
||||
{ value: 'CONFIDENTIAL', label: t('calendar', 'When shared show only busy') },
|
||||
{ value: 'PRIVATE', label: t('calendar', 'When shared hide this event') },
|
||||
],
|
||||
multiple: false,
|
||||
default: true,
|
||||
info: t('calendar', '')
|
||||
info: t('calendar', 'The visibility of this event in shared calendars.'),
|
||||
defaultValue: 'PUBLIC'
|
||||
},
|
||||
summary: {
|
||||
name: 'title',
|
||||
readableName: t('calendar', 'Title'),
|
||||
placeholder: t('calendar', 'Enter a title for this event')
|
||||
},
|
||||
location: {
|
||||
name: 'location',
|
||||
readableName: t('calendar', 'Location'),
|
||||
placeholder: t('calendar', 'Add or search for location'),
|
||||
icon: 'icon-address'
|
||||
},
|
||||
description: {
|
||||
name: 'description',
|
||||
readableName: t('calendar', 'Description'),
|
||||
icon: 'icon-text',
|
||||
multiple: false,
|
||||
default: true,
|
||||
info: t('calendar', '')
|
||||
placeholder: t('calendar', 'Add a description for yourself and your attendees'),
|
||||
icon: 'icon-menu',
|
||||
},
|
||||
geo: {
|
||||
name: 'geo',
|
||||
readableName: t('calendar', 'Geographic Position'),
|
||||
icon: 'icon-timezone',
|
||||
multiple: false,
|
||||
default: false,
|
||||
info: t('calendar', '')
|
||||
info: t('calendar', 'The geographical position this events take place at.')
|
||||
},
|
||||
priority: {
|
||||
readableName: t('calendar', 'Priority'),
|
||||
icon: '',
|
||||
multiple: false,
|
||||
default: false,
|
||||
info: t('calendar', ''),
|
||||
info: t('calendar', 'Priority of this event.'),
|
||||
options: [
|
||||
{ value: 7, label: t('calendar', 'low') },
|
||||
{ value: 5, label: t('calendar', 'medium') },
|
||||
{ value: 3, label: t('calendar', 'high') },
|
||||
{ value: 7, label: t('calendar', 'Low') },
|
||||
{ value: 5, label: t('calendar', 'Medium') },
|
||||
{ value: 3, label: t('calendar', 'High') },
|
||||
]
|
||||
|
||||
},
|
||||
status: {
|
||||
name: 'status',
|
||||
readableName: t('calendar', 'Status'),
|
||||
icon: '',
|
||||
multiple: false,
|
||||
default: false,
|
||||
info: t('calendar', '')
|
||||
|
||||
},
|
||||
transp: {
|
||||
readableName: t('calendar', 'Show as'),
|
||||
icon: '',
|
||||
multiple: false,
|
||||
default: false,
|
||||
info: t('calendar', ''),
|
||||
icon: 'icon-checkmark',
|
||||
options: [
|
||||
{ value: 'TRANSPARENT', label: t('calendar', 'free') },
|
||||
{ value: 'OPAQUE', label: t('calendar', 'busy') },
|
||||
]
|
||||
{ value: 'CONFIRMED', label: t('calendar', 'Confirmed') },
|
||||
{ value: 'TENTATIVE', label: t('calendar', 'Tentative') },
|
||||
{ value: 'CANCELLED', label: t('calendar', 'Cancelled') },
|
||||
],
|
||||
multiple: false,
|
||||
default: true,
|
||||
info: t('calendar', 'Confirmation about the overall status of the event.'),
|
||||
defaultValue: 'CONFIRMED'
|
||||
},
|
||||
timeTransparency: {
|
||||
name: 'timeTransparency',
|
||||
readableName: t('calendar', 'Show as'),
|
||||
icon: 'icon-briefcase',
|
||||
multiple: false,
|
||||
default: true,
|
||||
info: t('calendar', 'Take this event into account when calculating free-busy information'),
|
||||
options: [
|
||||
{ value: 'TRANSPARENT', label: t('calendar', 'Free') },
|
||||
{ value: 'OPAQUE', label: t('calendar', 'Busy') },
|
||||
],
|
||||
defaultValue: 'TRANSPARENT'
|
||||
},
|
||||
// url: {
|
||||
// readableName: t('calendar', 'URL'),
|
||||
|
@ -113,7 +135,7 @@ export const properties = {
|
|||
icon: '',
|
||||
multiple: false,
|
||||
default: false,
|
||||
info: t('calendar', '')
|
||||
info: t('calendar', 'Special color of this event. Overrides the calendar-color.')
|
||||
},
|
||||
// To be implemented later:
|
||||
// conference: {
|
||||
|
|
|
@ -46,7 +46,7 @@ export function getFCEventFromEventComponent(calendarObjects, start, end, timezo
|
|||
|
||||
const fcEvent = {
|
||||
id: [calendarObject.id, object.id].join('###'),
|
||||
title: object.title,
|
||||
title: object.title || t('calendar', 'Untitled event'),
|
||||
allDay: object.isAllDay(),
|
||||
start: object.startDate.getInTimezone(timezone).jsDate,
|
||||
end: object.endDate.getInTimezone(timezone).jsDate,
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
import Vue from 'vue'
|
||||
import CalendarObject from '../models/calendarObject'
|
||||
import logger from '../services/loggerService'
|
||||
// import logger from '../services/loggerService'
|
||||
import DateTimeValue from 'calendar-js/src/values/dateTimeValue'
|
||||
import { createEvent, getTimezoneManager } from 'calendar-js'
|
||||
|
||||
|
@ -41,11 +41,13 @@ const mutations = {
|
|||
*/
|
||||
appendCalendarObjects(state, calendarObjects = []) {
|
||||
for (const calendarObject of calendarObjects) {
|
||||
if (calendarObject instanceof CalendarObject) {
|
||||
if (!state.calendarObjects[calendarObject.id]) {
|
||||
Vue.set(state.calendarObjects, calendarObject.id, calendarObject)
|
||||
} else {
|
||||
logger.error('Invalid calendarObject object')
|
||||
}
|
||||
// if (calendarObject instanceof CalendarObject) {
|
||||
// } else {
|
||||
// logger.error('Invalid calendarObject object')
|
||||
// }
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -56,11 +58,13 @@ const mutations = {
|
|||
* @param {Object} calendarObject Calendar-object to add
|
||||
*/
|
||||
appendCalendarObject(state, calendarObject) {
|
||||
if (calendarObject instanceof CalendarObject) {
|
||||
if (!state.calendarObjects[calendarObject.id]) {
|
||||
Vue.set(state.calendarObjects, calendarObject.id, calendarObject)
|
||||
} else {
|
||||
logger.error('Invalid calendarObject object')
|
||||
}
|
||||
// if (calendarObject instanceof CalendarObject) {
|
||||
// } else {
|
||||
// logger.error('Invalid calendarObject object')
|
||||
// }
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -148,7 +152,7 @@ const actions = {
|
|||
* @returns {Promise<void>}
|
||||
*/
|
||||
async updateCalendarObject(context, { calendarObject }) {
|
||||
if (calendarObject.dav) {
|
||||
if (calendarObject.existsOnServer()) {
|
||||
calendarObject.dav.data = calendarObject.vcalendar.toICS()
|
||||
return calendarObject.dav.update()
|
||||
|
||||
|
@ -180,7 +184,7 @@ const actions = {
|
|||
async deleteCalendarObject(context, { calendarObject }) {
|
||||
// If this calendar-object was not created on the server yet,
|
||||
// no need to send requests to the server
|
||||
if (calendarObject.dav) {
|
||||
if (calendarObject.existsOnServer()) {
|
||||
await calendarObject.dav.delete()
|
||||
}
|
||||
|
||||
|
|
|
@ -1,35 +1,60 @@
|
|||
<!--
|
||||
- @copyright Copyright (c) 2019 Georg Ehrke <oc.list@georgehrke.com>
|
||||
- @copyright Copyright (c) 2019 Jakob Röhrl <jakob.roehrl@web.de>
|
||||
-
|
||||
- @author Georg Ehrke <oc.list@georgehrke.com>
|
||||
- @author Jakob Röhrl <jakob.roehrl@web.de>
|
||||
-
|
||||
- @license GNU AGPL version 3 or any later version
|
||||
-
|
||||
- This program is free software: you can redistribute it and/or modify
|
||||
- it under the terms of the GNU Affero General Public License as
|
||||
- published by the Free Software Foundation, either version 3 of the
|
||||
- License, or (at your option) any later version.
|
||||
-
|
||||
- This program is distributed in the hope that it will be useful,
|
||||
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
- GNU Affero General Public License for more details.
|
||||
-
|
||||
- You should have received a copy of the GNU Affero General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-
|
||||
-->
|
||||
|
||||
<template>
|
||||
<AppSidebar :title="title" :subtitle="subtitle" :compact="false"
|
||||
@close="cancel"
|
||||
>
|
||||
<template v-slot:primary-actions>
|
||||
<calendar-picker />
|
||||
<AppSidebar title="" :compact="false" @close="cancel">
|
||||
<template v-slot:primary-actions style="max-height: none !important">
|
||||
<div style="width: 100%">
|
||||
<property-title :event-component="eventComponent" :prop-model="rfcProps.summary" :is-read-only="false" />
|
||||
<calendar-picker :calendars="calendars" :calendar="selectedCalendar" />
|
||||
<!-- <property-timepicker-title :event-component="eventComponent" :is-read-only="false" />-->
|
||||
<!-- <title-timepicker :event-component="eventComponent" />-->
|
||||
<!-- <timezonepicker :event-component="eventComponent" />-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:secondary-actions>
|
||||
<ActionLink v-if="hasDownloadURL" icon="icon-download" title="Download"
|
||||
:href="downloadURL"
|
||||
/>
|
||||
<ActionButton v-if="canDelete && !canCreateRecurrenceException" icon="icon-delete" @click="alert('Delete')">
|
||||
Delete
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canDelete && canCreateRecurrenceException" icon="icon-delete" @click="alert('Delete')">
|
||||
Delete this occurrence
|
||||
</ActionButton>
|
||||
<ActionButton v-if="canDelete && canCreateRecurrenceException" icon="icon-delete" @click="alert('Delete')">
|
||||
Delete this and all future
|
||||
</ActionButton>
|
||||
</template>
|
||||
|
||||
<AppSidebarTab name="Details" icon="icon-details" :order="0">
|
||||
<title-timepicker :event-component="eventComponent" />
|
||||
<timezonepicker :event-component="eventComponent" />
|
||||
<div class="section-wrapper">
|
||||
<input v-model="location" type="text" placeholder="t('calendar', 'location')">
|
||||
</div>
|
||||
<div class="section-wrapper">
|
||||
<textarea v-model="description" placeholder="t('calendar', 'description')" />
|
||||
</div>
|
||||
<div class="section-wrapper">
|
||||
<Multiselect v-model="status" :options="statusOptions" />
|
||||
</div>
|
||||
<div class="section-wrapper">
|
||||
<Multiselect v-model="accessClass" :options="accessOptions" />
|
||||
</div>
|
||||
<div class="section-wrapper">
|
||||
<Multiselect v-model="timeTranspararency" :options="timeTranspararencyOptions" />
|
||||
</div>
|
||||
<property-text :event-component="eventComponent" :prop-model="rfcProps.location" :is-read-only="false" />
|
||||
<property-text :event-component="eventComponent" :prop-model="rfcProps.description" :is-read-only="false" />
|
||||
<property-select :event-component="eventComponent" :prop-model="rfcProps.status" :is-read-only="false" />
|
||||
<property-select :event-component="eventComponent" :prop-model="rfcProps.class" :is-read-only="false" />
|
||||
<property-select :event-component="eventComponent" :prop-model="rfcProps.timeTransparency" :is-read-only="false" />
|
||||
</AppSidebarTab>
|
||||
<AppSidebarTab name="Attendees" icon="icon-group" :order="1">
|
||||
This is the attendees tab
|
||||
|
@ -46,6 +71,18 @@
|
|||
<!-- <AppSidebarTab name="Projects" icon="icon-projects" :order="5">-->
|
||||
<!-- This is the projects tab-->
|
||||
<!-- </AppSidebarTab>-->
|
||||
|
||||
<div class="app-sidebar-button-area-bottom">
|
||||
<button v-if="!canCreateRecurrenceException" class="primary one-option">
|
||||
{{ updateLabel }}
|
||||
</button>
|
||||
<button v-if="canCreateRecurrenceException" class="primary two-options">
|
||||
Update this occurrence
|
||||
</button>
|
||||
<button v-if="canCreateRecurrenceException" class="two-options">
|
||||
Update this and all future
|
||||
</button>
|
||||
</div>
|
||||
</AppSidebar>
|
||||
</template>
|
||||
<script>
|
||||
|
@ -54,13 +91,18 @@ import {
|
|||
AppSidebar,
|
||||
AppSidebarTab,
|
||||
ActionLink,
|
||||
Multiselect
|
||||
ActionButton
|
||||
} from 'nextcloud-vue'
|
||||
import CalendarPicker from '../components/Editor/CalendarPicker'
|
||||
import TitleTimepicker from '../components/Editor/TitleTimepicker'
|
||||
import Timezonepicker from '../components/Editor/Timezonepicker'
|
||||
// import TitleTimepicker from '../components/Editor/TitleTimepicker'
|
||||
// import Timezonepicker from '../components/Editor/Timezonepicker'
|
||||
|
||||
import detectTimezone from '../services/timezoneDetectionService'
|
||||
import PropertyText from '../components/Editor/Properties/PropertyText'
|
||||
import PropertySelect from '../components/Editor/Properties/PropertySelect'
|
||||
|
||||
import rfcProps from '../models/rfcProps'
|
||||
import PropertyTitle from '../components/Editor/Properties/PropertyTitle'
|
||||
|
||||
// import { loadNewEventIntoEditor } from '../services/routerHelper'
|
||||
// import TitleTimepicker from '../components/Editor/TitleTimepicker'
|
||||
|
@ -72,13 +114,16 @@ import detectTimezone from '../services/timezoneDetectionService'
|
|||
export default {
|
||||
name: 'EditSidebar',
|
||||
components: {
|
||||
TitleTimepicker,
|
||||
Timezonepicker,
|
||||
PropertyTitle,
|
||||
PropertySelect,
|
||||
PropertyText,
|
||||
// TitleTimepicker,
|
||||
// Timezonepicker,
|
||||
AppSidebar,
|
||||
AppSidebarTab,
|
||||
ActionLink,
|
||||
ActionButton,
|
||||
CalendarPicker,
|
||||
Multiselect
|
||||
// TitleTimepicker,
|
||||
// DetailsTab,
|
||||
// InviteesTab,
|
||||
|
@ -89,84 +134,11 @@ export default {
|
|||
return {
|
||||
calendarObject: null,
|
||||
eventComponent: null,
|
||||
isLoading: false,
|
||||
isLoading: true,
|
||||
error: false,
|
||||
statusOptions: ['CONFIRMED', 'Tentative', 'Cancelled'],
|
||||
accessOptions: [
|
||||
'When shared show full event',
|
||||
'When shared show only busy',
|
||||
'When shared hide this event'
|
||||
],
|
||||
timeTranspararencyOptions: ['OPAQUE', 'TRANSPARENT']
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
title: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.title : ''
|
||||
},
|
||||
set(newValue) {
|
||||
this.eventComponent.title = newValue
|
||||
}
|
||||
},
|
||||
subtitle: {
|
||||
get() {
|
||||
return this.isLoading ? 'LOADING' : 'LOADED'
|
||||
},
|
||||
set(newValue) {
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
location: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.location : ''
|
||||
},
|
||||
set(newValue) {
|
||||
this.eventComponent.location = newValue
|
||||
}
|
||||
},
|
||||
description: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.description : ''
|
||||
},
|
||||
set(newValue) {
|
||||
this.eventComponent.description = newValue
|
||||
}
|
||||
|
||||
},
|
||||
status: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.status : ''
|
||||
},
|
||||
set(newValue) {
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
accessClass: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.accessClass : ''
|
||||
}
|
||||
|
||||
},
|
||||
timeTranspararency: {
|
||||
get() {
|
||||
return this.isLoading
|
||||
? 'LOADING'
|
||||
: this.eventComponent ? this.eventComponent.timeTranspararency : ''
|
||||
}
|
||||
},
|
||||
reminderIcon() {
|
||||
// Todo: show different icon based on alarm.
|
||||
// If no alarm is set: Show reminder icon without dot
|
||||
|
@ -190,6 +162,63 @@ export default {
|
|||
}
|
||||
|
||||
return this.calendarObject.dav.url + '?export'
|
||||
},
|
||||
displayDetails() {
|
||||
console.debug('display details?', (!this.isLoading && !this.error))
|
||||
return !this.isLoading && !this.error
|
||||
},
|
||||
rfcProps() {
|
||||
return rfcProps
|
||||
},
|
||||
canDelete() {
|
||||
if (!this.calendarObject) {
|
||||
return false
|
||||
}
|
||||
|
||||
return !!this.calendarObject.dav
|
||||
},
|
||||
canCreateRecurrenceException() {
|
||||
if (!this.eventComponent) {
|
||||
return false
|
||||
}
|
||||
|
||||
return this.eventComponent.canCreateRecurrenceExceptions()
|
||||
},
|
||||
updateLabel() {
|
||||
if (!this.calendarObject) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (!this.calendarObject.dav) {
|
||||
return t('calendar', 'Save')
|
||||
}
|
||||
|
||||
return t('calendar', 'Update')
|
||||
},
|
||||
updateOnlyThis() {
|
||||
return t('calendar', 'Update this occurrence')
|
||||
},
|
||||
updateThisAllFuture() {
|
||||
return t('calendar', 'Update this and all future')
|
||||
},
|
||||
isReadOnly() {
|
||||
return false
|
||||
},
|
||||
calendars() {
|
||||
if (this.isReadOnly) {
|
||||
return [
|
||||
this.$store.getters.getCalendarById(this.calendarObject.calendarId)
|
||||
]
|
||||
}
|
||||
|
||||
return this.$store.getters.sortedCalendars
|
||||
},
|
||||
selectedCalendar() {
|
||||
if (!this.calendarObject) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return this.$store.getters.getCalendarById(this.calendarObject.calendarId)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -216,7 +245,9 @@ export default {
|
|||
return
|
||||
}
|
||||
|
||||
console.debug('Can create a recurrence exception?', this.eventComponent.canCreateRecurrenceExceptions())
|
||||
if (this.eventComponent.canCreateRecurrenceExceptions() && this.calendarObject.id !== 'new') {
|
||||
console.debug('Creating a recurrence-exception')
|
||||
this.eventComponent.createRecurrenceException(thisAndAllFuture)
|
||||
}
|
||||
|
||||
|
@ -242,7 +273,7 @@ export default {
|
|||
},
|
||||
selectCalendar(selectedCalendar) {
|
||||
this.event = selectedCalendar
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeRouteEnter(to, from, next) {
|
||||
if (to.name === 'NewSidebarView') {
|
||||
|
@ -259,11 +290,8 @@ export default {
|
|||
vm.$store.dispatch('createNewEvent', { start, end, isAllDay, timezoneId })
|
||||
.then((calendarObject) => {
|
||||
vm.calendarObject = calendarObject
|
||||
vm.eventComponent = vm.calendarObject.getObjectAtRecurrenceId(new Date(start * 1000))
|
||||
vm.eventComponent = calendarObject.getObjectAtRecurrenceId(new Date(start * 1000))
|
||||
vm.isLoading = true
|
||||
|
||||
console.debug(vm.calendarObject)
|
||||
console.debug(vm.eventComponent)
|
||||
})
|
||||
})
|
||||
} else {
|
||||
|
@ -278,6 +306,7 @@ export default {
|
|||
.then(() => {
|
||||
vm.calendarObject = vm.$store.getters.getCalendarObjectById(objectId)
|
||||
vm.eventComponent = vm.calendarObject.getObjectAtRecurrenceId(new Date(recurrenceId * 1000))
|
||||
|
||||
vm.isLoading = false
|
||||
OCP.Toast.info('Loaded event ...')
|
||||
})
|
||||
|
@ -304,6 +333,7 @@ export default {
|
|||
.then(() => {
|
||||
this.calendarObject = this.$store.getters.getCalendarObjectById(objectId)
|
||||
this.eventComponent = this.calendarObject.getObjectAtRecurrenceId(new Date(recurrenceId * 1000))
|
||||
// this.getEventComponent = () => eventComponent
|
||||
this.isLoading = false
|
||||
OCP.Toast.info('Loaded event ...')
|
||||
|
||||
|
@ -329,11 +359,23 @@ export default {
|
|||
</script>
|
||||
|
||||
<style>
|
||||
.app-sidebar-button-area-bottom {
|
||||
position: absolute;
|
||||
margin-top: -60px;
|
||||
display: flex !important;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.section-wrapper {
|
||||
display: flex;
|
||||
max-width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
button.one-option {
|
||||
width: 100%
|
||||
}
|
||||
|
||||
button.two-options {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
.multiselect {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue