Skip to content

Commit 59f3375

Browse files
committed
Implement CRUD UI for appointment configs
Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
1 parent 592579d commit 59f3375

17 files changed

Lines changed: 1241 additions & 0 deletions

css/app-modal.scss

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Calendar App
3+
*
4+
* @copyright 2021 Richard Steinmetz <richard@steinmetz.cloud>
5+
*
6+
* @author Richard Steinmetz <richard@steinmetz.cloud>
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
10+
* License as published by the Free Software Foundation; either
11+
* version 3 of the License, or any later version.
12+
*
13+
* This library is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
17+
*
18+
* You should have received a copy of the GNU Affero General Public
19+
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
20+
*
21+
*/
22+
23+
.appointment-config-modal {
24+
}

css/app-navigation.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @author Raghu Nayyar
99
* @author Georg Ehrke
1010
* @author John Molakvoæ
11+
* @author Richard Steinmetz <richard@steinmetz.cloud>
1112
*
1213
* This library is free software; you can redistribute it and/or
1314
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -307,5 +308,11 @@
307308
}
308309
}
309310
}
311+
312+
.appointment-config-list {
313+
.app-navigation-caption {
314+
margin-top: 22px;
315+
}
316+
}
310317
}
311318
}

css/calendar.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
@import 'app-navigation.scss';
2323
@import 'app-sidebar.scss';
2424
@import 'app-settings.scss';
25+
@import 'app-modal.scss';
2526
@import 'freebusy.scss';
2627
@import 'fullcalendar.scss';
2728
@import 'global.scss';
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<!--
2+
- @copyright Copyright (c) 2021 Richard Steinmetz <richard@steinmetz.cloud>
3+
-
4+
- @author Richard Steinmetz <richard@steinmetz.cloud>
5+
-
6+
- @license GNU AGPL version 3 or any later version
7+
-
8+
- This program is free software: you can redistribute it and/or modify
9+
- it under the terms of the GNU Affero General Public License as
10+
- published by the Free Software Foundation, either version 3 of the
11+
- License, or (at your option) any later version.
12+
-
13+
- This program is distributed in the hope that it will be useful,
14+
- but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
- GNU Affero General Public License for more details.
17+
-
18+
- You should have received a copy of the GNU Affero General Public License
19+
- along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
-
21+
-->
22+
23+
<template>
24+
<div class="appointment-config-list">
25+
<AppNavigationCaption
26+
class="appointment-config-list__caption"
27+
:title="t('calendar', 'Appointment')">
28+
<template #actions>
29+
<ActionButton @click="showModalForNewConfig = true">
30+
<PlusIcon slot="icon" :size="20" decorative />
31+
{{ t('calendar', 'Add new') }}
32+
</ActionButton>
33+
</template>
34+
</AppNavigationCaption>
35+
<AppointmentConfigListItem
36+
v-for="config in configs"
37+
:key="config.id"
38+
:config="config" />
39+
40+
<AppointmentConfigModal
41+
v-if="showModalForNewConfig"
42+
:is-new="true"
43+
:config="defaultConfig"
44+
@save="saveNewConfig"
45+
@close="closeModal" />
46+
</div>
47+
</template>
48+
49+
<script>
50+
import AppointmentConfigListItem from './AppointmentConfigList/AppointmentConfigListItem'
51+
import AppNavigationCaption from '@nextcloud/vue/dist/Components/AppNavigationCaption'
52+
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
53+
import PlusIcon from 'vue-material-design-icons/Plus'
54+
import AppointmentConfigModal from '../AppointmentConfigModal'
55+
import AppointmentConfig, { generateAppointmentConfigs } from '../../models/appointmentConfig'
56+
import logger from '../../utils/logger'
57+
import { mapState } from 'vuex'
58+
59+
export default {
60+
name: 'AppointmentConfigList',
61+
components: {
62+
AppointmentConfigListItem,
63+
AppNavigationCaption,
64+
ActionButton,
65+
PlusIcon,
66+
AppointmentConfigModal,
67+
},
68+
data() {
69+
return {
70+
loading: false,
71+
showModalForNewConfig: false,
72+
}
73+
},
74+
computed: {
75+
...mapState({
76+
configs: state => Object.values(state.appointmentConfigs.configs),
77+
}),
78+
defaultConfig() {
79+
return new AppointmentConfig()
80+
},
81+
},
82+
async created() {
83+
for (const config of generateAppointmentConfigs()) {
84+
await this.$store.dispatch('addConfig', { config })
85+
}
86+
},
87+
methods: {
88+
closeModal() {
89+
this.showModalForNewConfig = false
90+
},
91+
async saveNewConfig(config) {
92+
logger.info('Saving new config', { config })
93+
94+
this.loading = true
95+
try {
96+
await this.$store.dispatch('addConfig', { config })
97+
this.closeModal()
98+
} catch (error) {
99+
logger.error('Creating appointment config failed', { error, config })
100+
} finally {
101+
this.loading = false
102+
}
103+
},
104+
},
105+
}
106+
</script>
107+
108+
<style lang="scss" scoped>
109+
</style>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!--
2+
- @copyright Copyright (c) 2021 Richard Steinmetz <richard@steinmetz.cloud>
3+
-
4+
- @author Richard Steinmetz <richard@steinmetz.cloud>
5+
-
6+
- @license GNU AGPL version 3 or any later version
7+
-
8+
- This program is free software: you can redistribute it and/or modify
9+
- it under the terms of the GNU Affero General Public License as
10+
- published by the Free Software Foundation, either version 3 of the
11+
- License, or (at your option) any later version.
12+
-
13+
- This program is distributed in the hope that it will be useful,
14+
- but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
- GNU Affero General Public License for more details.
17+
-
18+
- You should have received a copy of the GNU Affero General Public License
19+
- along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
-
21+
-->
22+
23+
<template>
24+
<div>
25+
<AppNavigationItem
26+
:title="config.name">
27+
<template #actions>
28+
<ActionButton @click="showModal = true">
29+
<PencilIcon slot="icon" :size="20" decorative />
30+
{{ t('calendar', 'Edit') }}
31+
</ActionButton>
32+
</template>
33+
</AppNavigationItem>
34+
<AppointmentConfigModal
35+
v-if="showModal"
36+
:is-new="false"
37+
:config="config"
38+
@save="save"
39+
@close="closeModal" />
40+
</div>
41+
</template>
42+
43+
<script>
44+
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
45+
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
46+
import PencilIcon from 'vue-material-design-icons/Pencil'
47+
import AppointmentConfig from '../../../models/appointmentConfig'
48+
import AppointmentConfigModal from '../../AppointmentConfigModal'
49+
import logger from '../../../utils/logger'
50+
51+
export default {
52+
name: 'AppointmentConfigListItem',
53+
components: {
54+
AppointmentConfigModal,
55+
AppNavigationItem,
56+
ActionButton,
57+
PencilIcon,
58+
},
59+
props: {
60+
config: {
61+
type: AppointmentConfig,
62+
required: true,
63+
},
64+
},
65+
data() {
66+
return {
67+
showModal: false,
68+
loading: false,
69+
}
70+
},
71+
methods: {
72+
closeModal() {
73+
this.showModal = false
74+
},
75+
async save(config) {
76+
logger.info('Saving existing config', { config })
77+
this.loading = true
78+
try {
79+
await this.$store.dispatch('updateConfig', { config })
80+
this.closeModal()
81+
} catch (error) {
82+
logger.error('Creating appointment config failed', { error, config })
83+
} finally {
84+
this.loading = false
85+
}
86+
},
87+
},
88+
}
89+
</script>
90+
91+
<style lang="scss" scoped>
92+
</style>

0 commit comments

Comments
 (0)