summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Kabo <raphaelkabo@hey.com>2023-10-10 15:18:12 +0100
committerRaphael Kabo <raphaelkabo@hey.com>2023-10-10 15:18:12 +0100
commit2f4ffd5d86aa695afaffed9c6780f695d0bfde9d (patch)
tree0f963b59a0bd18065ed55ab3e0aa220c3d3e3d7e
parent29e9314211376807c934f284e71aadce71a31ea3 (diff)
Improve group selector styling to use Select2
-rwxr-xr-xpublic/css/style.css68
-rw-r--r--public/js/modules/event-edit.js1
-rw-r--r--public/js/modules/group-linker.js90
-rw-r--r--public/js/modules/new.js3
-rwxr-xr-xviews/partials/eventForm.handlebars46
5 files changed, 141 insertions, 67 deletions
diff --git a/public/css/style.css b/public/css/style.css
index afa7471..d50ab11 100755
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -294,17 +294,22 @@ body, html {
.select2-selection__rendered {
line-height: 2.25rem !important;
}
-.select2-container .select2-selection--single {
- height: 2.25rem !important;
-}
+
.select2-selection__arrow {
- height: 2.25rem !important;
+ height: 100% !important;
}
-.select2-container--default .select2-selection--single {
+.select2-container .select2-selection--single {
/* Match Bootstrap 4 styling */
border: 1px solid #ced4da;
- height: calc(2.25rem + 2px);
+ height: 2.25rem;
+}
+
+.select2-results__option[aria-selected="true"] .group-preview__text,
+.select2-results__option[aria-selected="true"]
+ .group-preview__text
+ p.text-muted {
+ color: white !important;
}
.attendee-name {
@@ -413,26 +418,41 @@ article.static-page header {
border-bottom: 1px solid #e0e0e0;
}
-.card--group-preview {
+.select2-selection__rendered,
+.select2-selection--single {
+ overflow: hidden;
+}
+
+.group-preview {
display: grid;
grid-template-columns: 60px 1fr;
overflow: hidden;
gap: 1rem;
-
- transition: background-color 0.15s;
}
-.card--group-preview:hover {
- background-color: #f5f5f5;
+.select2-selection__rendered .group-preview {
+ transform: translateX(-8px);
}
-.card--group-preview img {
+img.group-preview__image {
width: 100%;
height: 60px;
object-fit: cover;
}
-.card--group-preview__text {
+.select2-container .select2-selection--single.group-select-dropdown {
+ height: 60px;
+}
+
+.select2-container
+ .select2-selection--single.group-select-dropdown
+ .select2-selection__rendered {
+ height: 100%;
+ display: flex;
+ align-items: center;
+}
+
+.group-preview__text {
text-decoration: none;
color: #1b1b1b;
overflow: hidden;
@@ -440,20 +460,17 @@ article.static-page header {
display: flex;
flex-direction: column;
justify-content: center;
+ line-height: 1.5;
}
-.card--group-preview__text strong,
-.card--group-preview__text p {
+.group-preview__text strong,
+.group-preview__text p {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin: 0;
}
-.card--group-preview:hover {
- text-decoration: none;
-}
-
@keyframes shimmer {
100% {
transform: translateX(100%);
@@ -492,3 +509,16 @@ article.static-page header {
left: 100%;
}
}
+
+.slider {
+ height: 0;
+ opacity: 0;
+ overflow: hidden;
+ transition: all 0.45s;
+ pointer-events: none;
+}
+
+.slider.slider--open {
+ opacity: 1;
+ pointer-events: auto;
+}
diff --git a/public/js/modules/event-edit.js b/public/js/modules/event-edit.js
index afe41d4..740c861 100644
--- a/public/js/modules/event-edit.js
+++ b/public/js/modules/event-edit.js
@@ -46,7 +46,6 @@ function editEventForm() {
this.data.timezone = event.target.value;
});
this.select2.val(this.data.timezone).trigger("change");
- console.log(JSON.stringify(this.data, null, 2));
// Set checkboxes
this.data.eventGroupCheckbox = !!window.eventData.eventGroupID;
diff --git a/public/js/modules/group-linker.js b/public/js/modules/group-linker.js
index ca5e159..a21fec3 100644
--- a/public/js/modules/group-linker.js
+++ b/public/js/modules/group-linker.js
@@ -5,23 +5,87 @@ function eventGroupLinker() {
eventGroupEditToken: "",
groups: [],
},
+ manualGroupInputVisible: false,
+ eventGroupOptionTemplate(state) {
+ if (!state.id) {
+ return state.text;
+ }
+ if (!this.data.groups.length) {
+ return state.text;
+ }
+ const group = this.data.groups.find(
+ (group) => group.id === state.id,
+ );
+ if (!group) {
+ return state.text;
+ }
+ const template = `
+ <span class="group-preview">
+ <img src="${
+ group.image
+ ? `/events/${group.image}`
+ : "/images/seigaiha-single.png"
+ }" class="group-preview__image" />
+ <div class="group-preview__text">
+ <strong>${group.name}</strong>
+ <p class="text-muted">${group.description}</p>
+ </div>
+ </span>`;
+ return $(template);
+ },
async init() {
+ this.select2 = $(this.$refs.eventGroupSelect).select2({
+ placeholder: "No group selected",
+ templateResult: this.eventGroupOptionTemplate.bind(this),
+ templateSelection: this.eventGroupOptionTemplate.bind(this),
+ selectionCssClass: "group-select-dropdown",
+ });
+ this.select2.on("select2:select", (event) => {
+ this.selectGroup(event);
+ });
+ this.select2.on("select2:unselect", () => {
+ this.data.eventGroupID = "";
+ this.data.eventGroupEditToken = "";
+ });
this.$watch("data.eventGroupID", () => {
this.$dispatch(
"event-group-id-changed",
this.data.eventGroupID,
);
+ const matchingGroup = this.data.groups.find(
+ (group) =>
+ group.id === this.data.eventGroupID &&
+ group.editToken === this.data.eventGroupEditToken,
+ );
+ if (matchingGroup) {
+ this.select2.val(matchingGroup.id).trigger("change");
+ } else {
+ this.resetGroupSelector();
+ }
});
this.$watch("data.eventGroupEditToken", () => {
this.$dispatch(
"event-group-edit-token-changed",
this.data.eventGroupEditToken,
);
+ const matchingGroup = this.data.groups.find(
+ (group) =>
+ group.id === this.data.eventGroupID &&
+ group.editToken === this.data.eventGroupEditToken,
+ );
+ if (matchingGroup) {
+ this.select2.val(matchingGroup.id).trigger("change");
+ } else {
+ this.resetGroupSelector();
+ }
});
- if (window.eventData && window.eventData.eventGroupID !== "") {
+ this.$watch("data.groups", () => {
+ this.select2.val(this.data.eventGroupID).trigger("change");
+ });
+ if (window.eventData && !!window.eventData.eventGroupID) {
this.data.eventGroupID = window.eventData.eventGroupID;
}
- if (window.eventData && window.eventGroupEditToken !== "") {
+ if (window.eventData && !!window.eventGroupEditToken) {
this.data.eventGroupEditToken =
window.eventData.eventGroupEditToken;
}
@@ -42,7 +106,7 @@ function eventGroupLinker() {
if (!response.ok) {
return;
}
- const json = await (await response).json();
+ const json = await response.json();
this.data.groups = json;
} catch (e) {
return false;
@@ -60,26 +124,8 @@ function eventGroupLinker() {
this.data.eventGroupID = group.id;
this.data.eventGroupEditToken = group.editToken;
},
- showGroupPreview() {
- return (
- this.data.eventGroupID !== "" &&
- this.data.groups.some(
- (group) =>
- group.id === this.data.eventGroupID &&
- group.editToken === this.data.eventGroupEditToken,
- )
- );
- },
- groupPreview() {
- if (!this.showGroupPreview()) {
- return {};
- }
- return this.data.groups.find(
- (group) => group.id === this.data.eventGroupID,
- );
- },
resetGroupSelector() {
- this.$refs.eventGroupSelect.value = "";
+ this.select2.val(null).trigger("change");
},
};
}
diff --git a/public/js/modules/new.js b/public/js/modules/new.js
index ca875bc..2d880f8 100644
--- a/public/js/modules/new.js
+++ b/public/js/modules/new.js
@@ -95,12 +95,13 @@ function newEventForm() {
errors: [],
submitting: false,
init() {
- // Set up Select2
+ // Set up timezone Select2
this.select2 = $(this.$refs.timezone).select2();
this.select2.on("select2:select", (event) => {
this.data.timezone = event.target.value;
});
this.data.timezone = this.select2.val();
+
// Reset checkboxes
this.data.eventGroupCheckbox = false;
this.data.interactionCheckbox = false;
diff --git a/views/partials/eventForm.handlebars b/views/partials/eventForm.handlebars
index 97e25af..c44a2ef 100755
--- a/views/partials/eventForm.handlebars
+++ b/views/partials/eventForm.handlebars
@@ -87,39 +87,37 @@
<label>Choose a group you've edited before</label>
</div>
<div class="form-group" x-show="data.groups.length > 0">
- <select x-ref="eventGroupSelect" id="eventGroupSelect" name="eventGroupSelect" class="form-control" x-on:change="selectGroup" x-model="data.eventGroupID">
- <option value="">Choose a group</option>
+ <select
+ x-ref="eventGroupSelect"
+ id="eventGroupSelect"
+ name="eventGroupSelect"
+ class="form-control"
+ x-on:change="selectGroup"
+ >
+ <option></option>
<template x-for="group in data.groups">
<option :value="group.id" x-text="group.name"></option>
</template>
</select>
</div>
- <a class="card shadow-sm card--group-preview mb-3" x-show="showGroupPreview()" x-bind:href="groupPreview().url" target="_blank">
- <template x-if="groupPreview().image">
- <img :src="'/events/' + groupPreview().image"/>
- </template>
- <template x-if="!groupPreview().image">
- <img src="/images/seigaiha-single.png"/>
- </template>
- <div class="card--group-preview__text">
- <strong x-text="groupPreview().name"></strong>
- <p x-text="groupPreview().description"></p>
- </div>
- </a>
- <div class="alert alert-info text-center" role="alert" x-show="data.groups.length > 0">
- <i class="fas fa-info-circle"></i> You can also enter the group ID and secret editing code manually.
- </div>
- <div class="form-group">
- <label for="eventGroupID">Event group ID</label>
+ <button type="button" class="btn btn-outline-secondary w-100 text-center" x-on:click="manualGroupInputVisible = !manualGroupInputVisible">
+ Enter group details manually <i class="fas" :class="{'fa-caret-down': !manualGroupInputVisible, 'fa-caret-up': manualGroupInputVisible}"></i>
+ </button>
+ <div
+ class="form-group slider"
+ id="manualGroupInput"
+ :class="manualGroupInputVisible && 'slider--open'"
+ :style="manualGroupInputVisible && {height: $el.scrollHeight+`px`}"
+ :aria-hidden="!manualGroupInputVisible"
+ >
+ <label for="eventGroupID" class="mt-2">Event group ID</label>
<div class="form-group">
- <input type="text" class="form-control" id="eventGroupID" name="eventGroupID" x-model="data.eventGroupID" x-on:input="resetGroupSelector">
+ <input type="text" class="form-control text-monospace" id="eventGroupID" name="eventGroupID" x-model="data.eventGroupID" x-on:input="resetGroupSelector">
<small class="form-text">You can find this short string of characters in the event group's link, in your confirmation email, or on the event group's page.</small>
</div>
- </div>
- <div class="form-group">
<label for="eventGroupEditToken">Event group secret editing code</label>
- <div class="form-group">
- <input type="text" class="form-control" id="eventGroupEditToken" name="eventGroupEditToken" x-model="data.eventGroupEditToken" x-on:input="resetGroupSelector">
+ <div class="form-group mb-0">
+ <input type="text" class="form-control text-monospace" id="eventGroupEditToken" name="eventGroupEditToken" x-model="data.eventGroupEditToken" x-on:input="resetGroupSelector">
<small class="form-text">You can find this long string of characters in the confirmation email you received when you created the event group.</small>
</div>
</div>