Allow editing announcements

This commit is contained in:
Tusooa Zhu 2022-03-17 17:11:53 -04:00 committed by tusooa
parent 0e51e824a2
commit 89c49b6fb4
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
6 changed files with 118 additions and 23 deletions

View File

@ -12,8 +12,10 @@ const Announcement = {
newAnnouncement: { newAnnouncement: {
content: '', content: '',
startsAt: undefined, startsAt: undefined,
endsAt: undefined endsAt: undefined,
} allDay: undefined
},
editError: ''
} }
}, },
props: { props: {
@ -58,6 +60,31 @@ const Announcement = {
formatTimeOrDate (time, locale) { formatTimeOrDate (time, locale) {
const d = new Date(time) const d = new Date(time)
return this.announcement['all_day'] ? d.toLocaleDateString(locale) : d.toLocaleString(locale) return this.announcement['all_day'] ? d.toLocaleDateString(locale) : d.toLocaleString(locale)
},
enterEditMode () {
this.newAnnouncement.content = this.announcement.pleroma['raw_content']
this.newAnnouncement.startsAt = this.announcement['starts_at']
this.newAnnouncement.endsAt = this.announcement['ends_at']
this.newAnnouncement.allDay = this.announcement['all_day']
this.editing = true
},
submitEdit () {
this.$store.dispatch('editAnnouncement', {
id: this.announcement.id,
...this.newAnnouncement
})
.then(() => {
this.editing = false
})
.catch(error => {
this.editError = error.error
})
},
cancelEdit () {
this.editing = false
},
clearError () {
this.editError = undefined
} }
} }
} }

View File

@ -16,7 +16,10 @@
/> />
</div> </div>
<div class="footer"> <div class="footer">
<div class="times"> <div
v-if="!editing"
class="times"
>
<span v-if="startsAt"> <span v-if="startsAt">
{{ $t('announcements.start_time_display', { time: startsAt }) }} {{ $t('announcements.start_time_display', { time: startsAt }) }}
</span> </span>
@ -24,7 +27,10 @@
{{ $t('announcements.end_time_display', { time: endsAt }) }} {{ $t('announcements.end_time_display', { time: endsAt }) }}
</span> </span>
</div> </div>
<div class="actions"> <div
v-if="!editing"
class="actions"
>
<button <button
v-if="currentUser" v-if="currentUser"
class="btn button-default" class="btn button-default"
@ -33,6 +39,13 @@
> >
{{ $t('announcements.mark_as_read_action') }} {{ $t('announcements.mark_as_read_action') }}
</button> </button>
<button
v-if="currentUser && currentUser.role === 'admin'"
class="btn button-default"
@click="enterEditMode"
>
{{ $t('announcements.edit_action') }}
</button>
<button <button
v-if="currentUser && currentUser.role === 'admin'" v-if="currentUser && currentUser.role === 'admin'"
class="btn button-default" class="btn button-default"
@ -41,6 +54,39 @@
{{ $t('announcements.delete_action') }} {{ $t('announcements.delete_action') }}
</button> </button>
</div> </div>
<div
v-else
class="actions"
>
<button
class="btn button-default"
@click="submitEdit"
>
{{ $t('announcements.submit_edit_action') }}
</button>
<button
class="btn button-default"
@click="cancelEdit"
>
{{ $t('announcements.cancel_edit_action') }}
</button>
<div
v-if="editing && editError"
class="alert error"
>
{{ $t('announcements.edit_error', { error }) }}
<button
class="button-unstyled"
@click="clearError"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
:title="$t('announcements.close_error')"
/>
</button>
</div>
</div>
</div> </div>
</div> </div>
</template> </template>

View File

@ -41,12 +41,20 @@
<script src="./announcement_editor.js"></script> <script src="./announcement_editor.js"></script>
<style lang="scss"> <style lang="scss">
.announcement-editor { .announcement-editor {
display: flex; display: flex;
align-items: stretch; align-items: stretch;
flex-direction: column; flex-direction: column;
.announcement-metadata {
margin-top: 0.5em; .announcement-metadata {
} margin-top: 0.5em;
} }
.post-textarea {
resize: vertical;
height: 10em;
overflow: none;
box-sizing: content-box;
}
}
</style> </style>

View File

@ -71,13 +71,6 @@
margin-bottom: var(--status-margin, $status-margin); margin-bottom: var(--status-margin, $status-margin);
} }
.post-textarea {
resize: vertical;
height: 10em;
overflow: none;
box-sizing: content-box;
}
.post-button { .post-button {
min-width: 10em; min-width: 10em;
} }

View File

@ -65,6 +65,12 @@ const announcements = {
return store.dispatch('fetchAnnouncements') return store.dispatch('fetchAnnouncements')
}) })
}, },
editAnnouncement (store, { id, content, startsAt, endsAt, allDay }) {
return store.rootState.api.backendInteractor.editAnnouncement({ id, content, startsAt, endsAt, allDay })
.then(() => {
return store.dispatch('fetchAnnouncements')
})
},
deleteAnnouncement (store, id) { deleteAnnouncement (store, id) {
return store.rootState.api.backendInteractor.deleteAnnouncement({ id }) return store.rootState.api.backendInteractor.deleteAnnouncement({ id })
.then(() => { .then(() => {

View File

@ -104,6 +104,7 @@ const PLEROMA_ADMIN_REPORTS = '/api/pleroma/admin/reports'
const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups' const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_ANNOUNCEMENTS_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements' const PLEROMA_POST_ANNOUNCEMENT_URL = '/api/v1/pleroma/admin/announcements'
const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}` const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
const oldfetch = window.fetch const oldfetch = window.fetch
@ -1382,26 +1383,39 @@ const dismissAnnouncement = ({ id, credentials }) => {
}) })
} }
const postAnnouncement = ({ credentials, content, startsAt, endsAt, allDay }) => { const announcementToPayload = ({ content, startsAt, endsAt, allDay }) => {
const payload = { content } const payload = { content }
if (typeof startsAt !== 'undefined') { if (typeof startsAt !== 'undefined') {
payload['starts_at'] = new Date(startsAt).toISOString() payload['starts_at'] = startsAt ? new Date(startsAt).toISOString() : null
} }
if (typeof endsAt !== 'undefined') { if (typeof endsAt !== 'undefined') {
payload['ends_at'] = new Date(endsAt).toISOString() payload['ends_at'] = endsAt ? new Date(endsAt).toISOString() : null
} }
if (typeof allDay !== 'undefined') { if (typeof allDay !== 'undefined') {
payload['all_day'] = allDay payload['all_day'] = allDay
} }
return payload
}
const postAnnouncement = ({ credentials, content, startsAt, endsAt, allDay }) => {
return promisedRequest({ return promisedRequest({
url: PLEROMA_POST_ANNOUNCEMENT_URL, url: PLEROMA_POST_ANNOUNCEMENT_URL,
credentials, credentials,
method: 'POST', method: 'POST',
payload payload: announcementToPayload({ content, startsAt, endsAt, allDay })
})
}
const editAnnouncement = ({ id, credentials, content, startsAt, endsAt, allDay }) => {
return promisedRequest({
url: PLEROMA_EDIT_ANNOUNCEMENT_URL(id),
credentials,
method: 'PATCH',
payload: announcementToPayload({ content, startsAt, endsAt, allDay })
}) })
} }
@ -1743,6 +1757,7 @@ const apiService = {
fetchAnnouncements, fetchAnnouncements,
dismissAnnouncement, dismissAnnouncement,
postAnnouncement, postAnnouncement,
editAnnouncement,
deleteAnnouncement, deleteAnnouncement,
adminFetchAnnouncements adminFetchAnnouncements
} }