FEATURE: allows to manually close an event

This commit is contained in:
jjaffeux 2020-08-07 21:43:55 +02:00
parent 6754bdfc8b
commit 519f52238e
6 changed files with 131 additions and 72 deletions

View File

@ -8,6 +8,8 @@ import { equal } from "@ember/object/computed";
import { extractError } from "discourse/lib/ajax-error"; import { extractError } from "discourse/lib/ajax-error";
import { Promise } from "rsvp"; import { Promise } from "rsvp";
import { buildParams, replaceRaw } from "../../lib/raw-event-helper";
export default Controller.extend(ModalFunctionality, { export default Controller.extend(ModalFunctionality, {
init() { init() {
this._super(...arguments); this._super(...arguments);
@ -116,7 +118,11 @@ export default Controller.extend(ModalFunctionality, {
return; return;
} }
const eventParams = this._buildEventParams(); const eventParams = buildParams(
this.startsAt,
this.endsAt,
this.model.eventModel
);
const markdownParams = []; const markdownParams = [];
Object.keys(eventParams).forEach(key => { Object.keys(eventParams).forEach(key => {
let value = eventParams[key]; let value = eventParams[key];
@ -145,8 +151,12 @@ export default Controller.extend(ModalFunctionality, {
const updateRawPromise = new Promise(resolve => { const updateRawPromise = new Promise(resolve => {
const raw = post.raw; const raw = post.raw;
const eventParams = this._buildEventParams(); const eventParams = buildParams(
const newRaw = this._replaceRawEvent(eventParams, raw); this.startsAt,
this.endsAt,
this.model.eventModel
);
const newRaw = replaceRaw(eventParams, raw);
if (newRaw) { if (newRaw) {
const props = { const props = {
@ -171,67 +181,8 @@ export default Controller.extend(ModalFunctionality, {
}); });
}, },
_buildEventParams() {
const eventParams = {};
if (this.startsAt) {
eventParams.start = moment(this.startsAt)
.utc()
.format("YYYY-MM-DD HH:mm");
} else {
eventParams.start = moment()
.utc()
.format("YYYY-MM-DD HH:mm");
}
if (this.model.eventModel.status) {
eventParams.status = this.model.eventModel.status;
}
if (this.model.eventModel.name) {
eventParams.name = this.model.eventModel.name;
}
if (this.model.eventModel.url) {
eventParams.url = this.model.eventModel.url;
}
if (this.endsAt) {
eventParams.end = moment(this.endsAt)
.utc()
.format("YYYY-MM-DD HH:mm");
}
if (this.model.eventModel.status === "private") {
eventParams.allowedGroups = (
this.model.eventModel.raw_invitees || []
).join(",");
}
return eventParams;
},
_removeRawEvent(raw) { _removeRawEvent(raw) {
const eventRegex = new RegExp(`\\[event\\s(.*?)\\]\\n\\[\\/event\\]`, "m"); const eventRegex = new RegExp(`\\[event\\s(.*?)\\]\\n\\[\\/event\\]`, "m");
return raw.replace(eventRegex, ""); return raw.replace(eventRegex, "");
},
_replaceRawEvent(eventParams, raw) {
const eventRegex = new RegExp(`\\[event\\s(.*?)\\]`, "m");
const eventMatches = raw.match(eventRegex);
if (eventMatches && eventMatches[1]) {
const markdownParams = [];
Object.keys(eventParams).forEach(eventParam => {
const value = eventParams[eventParam];
if (value && value.length) {
markdownParams.push(`${eventParam}="${eventParams[eventParam]}"`);
}
});
return raw.replace(eventRegex, `[event ${markdownParams.join(" ")}]`);
}
return false;
} }
}); });

View File

@ -1,3 +1,4 @@
import TextLib from "discourse/lib/text";
import { exportEntity } from "discourse/lib/export-csv"; import { exportEntity } from "discourse/lib/export-csv";
import { emojiUnescape } from "discourse/lib/text"; import { emojiUnescape } from "discourse/lib/text";
import cleanTitle from "discourse/plugins/discourse-calendar/lib/clean-title"; import cleanTitle from "discourse/plugins/discourse-calendar/lib/clean-title";
@ -8,6 +9,7 @@ import hbs from "discourse/widgets/hbs-compiler";
import { createWidget } from "discourse/widgets/widget"; import { createWidget } from "discourse/widgets/widget";
import { routeAction } from "discourse/helpers/route-action"; import { routeAction } from "discourse/helpers/route-action";
import getURL from "discourse-common/lib/get-url"; import getURL from "discourse-common/lib/get-url";
import { buildParams, replaceRaw } from "../../lib/raw-event-helper";
export default createWidget("discourse-post-event", { export default createWidget("discourse-post-event", {
tagName: "div.discourse-post-event-widget", tagName: "div.discourse-post-event-widget",
@ -53,6 +55,39 @@ export default createWidget("discourse-post-event", {
}); });
}, },
closePostEvent(eventModel) {
bootbox.confirm(
I18n.t("discourse_post_event.builder_modal.confirm_close"),
I18n.t("no_value"),
I18n.t("yes_value"),
confirmed => {
if (confirmed) {
return this.store.find("post", eventModel.id).then(post => {
const raw = post.raw;
const eventParams = buildParams(
eventModel.starts_at ? moment(eventModel.starts_at) : moment(),
moment(),
eventModel
);
const newRaw = replaceRaw(eventParams, raw);
if (newRaw) {
const props = {
raw: newRaw,
edit_reason: I18n.t("discourse_post_event.edit_reason")
};
return TextLib.cookAsync(newRaw).then(cooked => {
props.cooked = cooked.string;
return post.save(props);
});
}
});
}
}
);
},
changeWatchingInviteeStatus(status) { changeWatchingInviteeStatus(status) {
if (this.state.eventModel.watching_invitee) { if (this.state.eventModel.watching_invitee) {
this.store.update( this.store.update(
@ -167,10 +202,8 @@ export default createWidget("discourse-post-event", {
widget="more-dropdown" widget="more-dropdown"
attrs=(hash attrs=(hash
canActOnEvent=this.transformed.canActOnEvent canActOnEvent=this.transformed.canActOnEvent
postEventId=state.eventModel.id
isExpired=state.eventModel.is_expired
creatorUsername=state.eventModel.creator.username
isPublicEvent=this.transformed.isPublicEvent isPublicEvent=this.transformed.isPublicEvent
eventModel=state.eventModel
) )
}} }}
</header> </header>

View File

@ -38,7 +38,7 @@ export default createWidget("more-dropdown", {
_buildContent(attrs) { _buildContent(attrs) {
const content = []; const content = [];
if (!attrs.isExpired) { if (!attrs.eventModel.is_expired) {
content.push({ content.push({
id: "addToCalendar", id: "addToCalendar",
icon: "file", icon: "file",
@ -52,17 +52,17 @@ export default createWidget("more-dropdown", {
icon: "envelope", icon: "envelope",
translatedLabel: I18n.t( translatedLabel: I18n.t(
"discourse_post_event.event_ui.send_pm_to_creator", "discourse_post_event.event_ui.send_pm_to_creator",
{ username: attrs.creatorUsername } { username: attrs.eventModel.creator.username }
) )
}); });
} }
if (!attrs.isExpired && attrs.canActOnEvent && attrs.isPublicEvent) { if (!attrs.is_expired && attrs.canActOnEvent && attrs.isPublicEvent) {
content.push({ content.push({
id: "inviteUserOrGroup", id: "inviteUserOrGroup",
icon: "user-plus", icon: "user-plus",
label: "discourse_post_event.event_ui.invite", label: "discourse_post_event.event_ui.invite",
param: attrs.postEventId param: attrs.eventModel.id
}); });
} }
@ -73,22 +73,32 @@ export default createWidget("more-dropdown", {
icon: "file-csv", icon: "file-csv",
id: "exportPostEvent", id: "exportPostEvent",
label: "discourse_post_event.event_ui.export_event", label: "discourse_post_event.event_ui.export_event",
param: attrs.postEventId param: attrs.eventModel.id
}); });
content.push({ content.push({
icon: "file-upload", icon: "file-upload",
id: "bulkInvite", id: "bulkInvite",
label: "discourse_post_event.event_ui.bulk_invite", label: "discourse_post_event.event_ui.bulk_invite",
param: attrs.postEventId param: attrs.eventModel.id
}); });
content.push({ content.push({
icon: "pencil-alt", icon: "pencil-alt",
id: "editPostEvent", id: "editPostEvent",
label: "discourse_post_event.event_ui.edit_event", label: "discourse_post_event.event_ui.edit_event",
param: attrs.postEventId param: attrs.eventModel.id
}); });
if (!attrs.eventModel.is_expired) {
content.push({
icon: "times",
id: "closePostEvent",
label: "discourse_post_event.event_ui.close_event",
class: "danger",
param: attrs.eventModel
});
}
} }
return content; return content;

View File

@ -0,0 +1,56 @@
export function buildParams(startsAt, endsAt, eventModel) {
const params = {};
if (startsAt) {
params.start = moment(startsAt)
.utc()
.format("YYYY-MM-DD HH:mm");
} else {
params.start = moment()
.utc()
.format("YYYY-MM-DD HH:mm");
}
if (eventModel.status) {
params.status = eventModel.status;
}
if (eventModel.name) {
params.name = eventModel.name;
}
if (eventModel.url) {
params.url = eventModel.url;
}
if (endsAt) {
params.end = moment(endsAt)
.utc()
.format("YYYY-MM-DD HH:mm");
}
if (eventModel.status === "private") {
params.allowedGroups = (eventModel.raw_invitees || []).join(",");
}
return params;
}
export function replaceRaw(params, raw) {
const eventRegex = new RegExp(`\\[event\\s(.*?)\\]`, "m");
const eventMatches = raw.match(eventRegex);
if (eventMatches && eventMatches[1]) {
const markdownParams = [];
Object.keys(params).forEach(param => {
const value = params[param];
if (value && value.length) {
markdownParams.push(`${param}="${params[param]}"`);
}
});
return raw.replace(eventRegex, `[event ${markdownParams.join(" ")}]`);
}
return false;
}

View File

@ -62,6 +62,13 @@
display: none; display: none;
} }
} }
.item-closePostEvent {
.d-icon,
span {
color: $danger;
}
}
} }
} }
} }

View File

@ -305,6 +305,7 @@ en:
export_event: Export event export_event: Export event
created_by: Created by created_by: Created by
bulk_invite: Bulk Invite bulk_invite: Bulk Invite
close_event: Close event
invitees_modal: invitees_modal:
title_invited: "List of invited users" title_invited: "List of invited users"
title_participated: "List of users who participated" title_participated: "List of users who participated"
@ -326,6 +327,7 @@ en:
create_event_title: Create Event create_event_title: Create Event
update_event_title: Edit Event update_event_title: Edit Event
confirm_delete: Are you sure you want to delete this event? confirm_delete: Are you sure you want to delete this event?
confirm_close: Are you sure you want to close this event?
create: Create create: Create
update: Save update: Save
attach: Create event attach: Create event