Skip to content

Commit c3f9fd4

Browse files
Calendar: Preserve previously selected event color on edit - refs #4206
1 parent aa12293 commit c3f9fd4

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

assets/vue/components/ccalendarevent/CCalendarEventForm.vue

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
</template>
5151

5252
<script setup>
53-
import { computed, ref, watch } from "vue"
53+
import { computed, ref, watch, onMounted } from "vue"
5454
import { useRoute } from "vue-router"
5555
import { useVuelidate } from "@vuelidate/core"
5656
import { required } from "@vuelidate/validators"
@@ -134,8 +134,42 @@ function getDefaultColorByType(type) {
134134
return defaultColors[type] || defaultColors.personal
135135
}
136136
137-
if (!item.value.color) {
138-
const type = getContextTypeFromRoute()
139-
item.value.color = getDefaultColorByType(type)
137+
const HEX6 = /^#([0-9a-f]{6})$/i
138+
const HEX3 = /^#([0-9a-f]{3})$/i
139+
function toHex(c) {
140+
if (!c) return null
141+
const s = String(c).trim()
142+
if (HEX6.test(s)) return s.toUpperCase()
143+
const m3 = s.match(HEX3)
144+
if (m3) {
145+
const [r, g, b] = m3[1].toUpperCase().split("")
146+
return `#${r}${r}${g}${g}${b}${b}`
147+
}
148+
const rgb = s.match(/rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})/i)
149+
if (rgb) {
150+
const r = Math.min(255, +rgb[1])
151+
const g = Math.min(255, +rgb[2])
152+
const b = Math.min(255, +rgb[3])
153+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`.toUpperCase()
154+
}
155+
const names = {
156+
YELLOW: "#FFFF00",
157+
BLUE: "#0000FF",
158+
RED: "#FF0000",
159+
GREEN: "#008000",
160+
STEELBLUE: "#4682B4",
161+
"STEEL BLUE": "#4682B4",
162+
}
163+
return names[s.toUpperCase()] || null
140164
}
165+
166+
onMounted(() => {
167+
const normalized = toHex(item.value?.color)
168+
if (normalized) {
169+
item.value.color = normalized
170+
} else if (!item.value?.color) {
171+
const type = getContextTypeFromRoute()
172+
item.value.color = getDefaultColorByType(type)
173+
}
174+
})
141175
</script>

assets/vue/views/ccalendarevent/CCalendarEventList.vue

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,43 @@ const calendarLocale = allLocales.find(
212212
calLocale.code === appLocale.value.replace("_", "-") || calLocale.code === useParentLocale(appLocale.value),
213213
)
214214
215+
const HEX6 = /^#([0-9a-f]{6})$/i
216+
const HEX3 = /^#([0-9a-f]{3})$/i
217+
function normalizeHex(c) {
218+
if (!c) return null
219+
const s = String(c).trim()
220+
if (HEX6.test(s)) return s.toUpperCase()
221+
const m3 = s.match(HEX3)
222+
if (m3) {
223+
const [r, g, b] = m3[1].toUpperCase().split("")
224+
return `#${r}${r}${g}${g}${b}${b}`
225+
}
226+
const mRgb = s.match(/rgba?\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})/i)
227+
if (mRgb) {
228+
const r = Math.min(255, +mRgb[1])
229+
const g = Math.min(255, +mRgb[2])
230+
const b = Math.min(255, +mRgb[3])
231+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`.toUpperCase()
232+
}
233+
const names = {
234+
YELLOW: "#FFFF00",
235+
BLUE: "#0000FF",
236+
RED: "#FF0000",
237+
GREEN: "#008000",
238+
STEELBLUE: "#4682B4",
239+
"STEEL BLUE": "#4682B4",
240+
}
241+
return names[s.toUpperCase()] || null
242+
}
243+
244+
function defaultColorByContext(ctx) {
245+
return ctx === "global" ? "#FF0000" : ctx === "course" ? "#458B00" : ctx === "session" ? "#00496D" : "#4682B4"
246+
}
247+
215248
const showAddEventDialog = () => {
216249
item.value = {}
217250
item.value["parentResourceNode"] = securityStore.user.resourceNode["id"]
251+
item.value["color"] = defaultColorByContext(currentContext.value)
218252
219253
dialog.value = true
220254
}
@@ -257,6 +291,8 @@ const calendarOptions = ref({
257291
item.value["endDate"] = event.end ? new Date(event.end) : null
258292
item.value["parentResourceNodeId"] = event.extendedProps?.resourceNode?.creator?.id
259293
294+
const rawColor = event.extendedProps?.color ?? event.backgroundColor ?? event.borderColor ?? event.color ?? null
295+
item.value["color"] = normalizeHex(rawColor) || defaultColorByContext(currentContext.value)
260296
if (
261297
!(route.query.sid === "0" && item.value.type === "session") &&
262298
!(route.query.sid !== "0" && item.value.type === "course") &&
@@ -303,6 +339,7 @@ const calendarOptions = ref({
303339
item.value["allDay"] = info.allDay
304340
item.value["startDate"] = startDate
305341
item.value["endDate"] = endDate
342+
item.value["color"] = defaultColorByContext(currentContext.value)
306343
307344
dialog.value = true
308345
},
@@ -455,6 +492,10 @@ async function onCreateEventForm() {
455492
itemModel.isGlobal = true
456493
}
457494
495+
if (!itemModel.color) {
496+
itemModel.color = defaultColorByContext(currentContext.value)
497+
}
498+
458499
if (itemModel["@id"]) {
459500
await store.dispatch("ccalendarevent/update", itemModel)
460501
} else {

0 commit comments

Comments
 (0)