From 0385643f99d64ae6826339938c6cb3d183a1a39d Mon Sep 17 00:00:00 2001 From: Qiyun Dai Date: Fri, 30 Aug 2024 20:27:18 -0500 Subject: [PATCH] event-info duplication prevention added --- .../event-info-component.css | 9 ++++++++ .../event-info-component.js | 2 +- .../event-format-component-controller.js | 9 ++++++-- .../event-info-component-controller.js | 23 ++++++++++++++++++- ecc/scripts/utils.js | 6 ++++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/ecc/blocks/event-info-component/event-info-component.css b/ecc/blocks/event-info-component/event-info-component.css index 413e2229..9d326171 100644 --- a/ecc/blocks/event-info-component/event-info-component.css +++ b/ecc/blocks/event-info-component/event-info-component.css @@ -11,6 +11,15 @@ width: 100%; } +.event-info-component sp-textfield#info-field-event-title sp-help-text { + position: absolute; + display: none; +} + +.event-info-component sp-textfield#info-field-event-title.show-negative-help-text sp-help-text { + display: flex; +} + .event-info-component sp-textfield.textarea-input { font-size: var(--type-body-m-size);; width: 100%; diff --git a/ecc/blocks/event-info-component/event-info-component.js b/ecc/blocks/event-info-component/event-info-component.js index a938ee97..3197c4ae 100644 --- a/ecc/blocks/event-info-component/event-info-component.js +++ b/ecc/blocks/event-info-component/event-info-component.js @@ -94,7 +94,7 @@ export default function init(el) { generateToolTip(r); break; case 1: - await decorateTextfield(r, { id: 'info-field-event-title' }); + await decorateTextfield(r, { id: 'info-field-event-title' }, 'This event title is already taken'); break; case 2: await decorateTextarea(r, { id: 'info-field-event-description', grows: true, quiet: true }); diff --git a/ecc/blocks/form-handler/controllers/event-format-component-controller.js b/ecc/blocks/form-handler/controllers/event-format-component-controller.js index d0f0951e..9b3ac1fc 100644 --- a/ecc/blocks/form-handler/controllers/event-format-component-controller.js +++ b/ecc/blocks/form-handler/controllers/event-format-component-controller.js @@ -67,7 +67,7 @@ export async function onUpdate(component, props) { } } -async function populateSeriesOptions(component) { +async function populateSeriesOptions(props, component) { const seriesSelect = component.querySelector('#series-select-input'); if (!seriesSelect) return; @@ -84,6 +84,11 @@ async function populateSeriesOptions(component) { }); seriesSelect.pending = false; + + seriesSelect.addEventListener('change', () => { + const seriesId = seriesSelect.value; + props.payload = { ...props.payload, ...{ seriesId } }; + }); } export default async function init(component, props) { @@ -104,7 +109,7 @@ export default async function init(component, props) { const eventData = props.eventDataResp; prepopulateTimeZone(component); initStepLock(component); - await populateSeriesOptions(component); + await populateSeriesOptions(props, component); const { cloudType, diff --git a/ecc/blocks/form-handler/controllers/event-info-component-controller.js b/ecc/blocks/form-handler/controllers/event-info-component-controller.js index 4b6e042c..27c655b7 100644 --- a/ecc/blocks/form-handler/controllers/event-info-component-controller.js +++ b/ecc/blocks/form-handler/controllers/event-info-component-controller.js @@ -1,5 +1,6 @@ /* eslint-disable no-unused-vars */ /* eslint-disable no-use-before-define */ +import { getEvents } from '../../../scripts/esp-controller.js'; import { LIBS } from '../../../scripts/scripts.js'; import { changeInputValue } from '../../../scripts/utils.js'; @@ -345,14 +346,34 @@ export async function onUpdate(component, props) { // do nothing } -export default function init(component, props) { +export default async function init(component, props) { + const allEventsResp = await getEvents(); + const allEvents = allEventsResp?.events; const eventData = props.eventDataResp; + + const eventTitleInput = component.querySelector('#info-field-event-title'); const startTimeInput = component.querySelector('#time-picker-start-time'); const endTimeInput = component.querySelector('#time-picker-end-time'); const datePicker = component.querySelector('#event-info-date-picker'); initCalendar(component); + eventTitleInput.addEventListener('change', () => { + const sameSeriesEvents = allEvents?.filter((e) => { + const matchInPayload = e.seriesId === props.payload.seriesId; + const matchInResp = e.seriesId === eventData.seriesId; + return matchInPayload || matchInResp; + }) || []; + + if (sameSeriesEvents.some((event) => event.title === eventTitleInput.value)) { + eventTitleInput.classList.add('show-negative-help-text'); + eventTitleInput.invalid = true; + } else { + eventTitleInput.classList.remove('show-negative-help-text'); + eventTitleInput.invalid = false; + } + }); + endTimeInput.addEventListener('change', () => { if (datePicker.dataset.startDate !== datePicker.dataset.endDate) return; const allOptions = startTimeInput.querySelectorAll('sp-menu-item'); diff --git a/ecc/scripts/utils.js b/ecc/scripts/utils.js index 5ba58ece..adeffa38 100644 --- a/ecc/scripts/utils.js +++ b/ecc/scripts/utils.js @@ -125,7 +125,7 @@ function mergeOptions(defaultOptions, overrideOptions) { return combinedOptions; } -export async function decorateTextfield(cell, extraOptions) { +export async function decorateTextfield(cell, extraOptions, negativeHelperText = '') { cell.classList.add('text-field-row'); const cols = cell.querySelectorAll(':scope > div'); if (!cols.length) return; @@ -153,6 +153,10 @@ export async function decorateTextfield(cell, extraOptions) { extraOptions, )); + if (negativeHelperText) { + createTag('sp-help-text', { variant: 'negative', slot: 'negative-help-text', icon: true }, negativeHelperText, { parent: input }); + } + if (maxCharNum) input.setAttribute('maxlength', maxCharNum); const wrapper = createTag('div', { class: 'info-field-wrapper' });