default_overflow, ui fixes, cleanups

This commit is contained in:
Kara Engelhardt committed 2026-10-27 17:52:47 +01:00
1 parent 753de714a3
commit 63bf3f3eca
9 files changed
+80 -28

No files matched your search

@@ -64,7 +64,7 @@ const previewRenderers = {
template(v-if="!store.loaded") {{ gettext("Loading...") }}
form(v-else @submit.prevent="store.save")
.form-group
Input(label="Name" v-model="store.name")
Input(label="Name" v-model="store.name" required="true")
nav
ul.nav.nav-tabs
li(v-for="platform in store.platforms" :class="{'active': store.platform.identifier === platform.identifier}")
@@ -37,7 +37,7 @@ function addEntry() {
watchEffect(() => {
if (!fieldConfig.value) {
fieldConfig.value = {
overflow: null,
overflow: props.fieldgroup.default_overflow,
entries: JSON.parse(JSON.stringify(props.fieldgroup.default_entries)),
};
}
@@ -29,7 +29,7 @@ const theme = computed(() => {
.f-row.head-row
img.logo(:src="store.getSettingValue('logo')?.url")
div.logo-text {{ store.renderedFieldGroups['logo_text']?.[0]?.content }}
FieldGroupEntries.header(fieldgroup="header")
FieldGroupEntries.header.f-row(fieldgroup="header")
.f-column
FieldGroupEntries.primary(fieldgroup="primary")
@@ -80,7 +80,7 @@ const theme = computed(() => {
font-size: 1.5em;
font-weight: bold;
min-height: 2lh;
flex: 1 1 3;
flex: 1 1;
align-content: center;
text-wrap: nowrap;
}
@@ -89,6 +89,7 @@ const theme = computed(() => {
text-align: end;
line-height: 1.25;
gap: 0.25rem;
justify-content: end;
.pass-content {
font-size: 1.25em;
}
@@ -48,6 +48,7 @@ type PlaceholderFieldGroupDefinition = BaseFieldGroupDefinition & {
max_entries: number | null;
context_args: string[];
overflows: string[];
default_overflow: string | null;
};
type PredefinedFieldGroupDefinition = BaseFieldGroupDefinition & {
@@ -101,7 +102,7 @@ type LayoutData = {
type PlatformLayout = {
style: string;
fieldgroups: {};
fieldgroups: Record<string, FieldGroupConfig>;
settings: {};
file_settings: Record<string, WalletFile>;
};
@@ -12,7 +12,7 @@ function getDefaultFieldgroupState(
return { active: fieldgroup.required || fieldgroup.default_active };
} else if (fieldgroup.type == "placeholder") {
return {
overflow: null,
overflow: fieldgroup.default_overflow,
entries: JSON.parse(JSON.stringify(fieldgroup.default_entries)),
};
}
@@ -297,6 +297,32 @@ export function createWalletStore(config: {
})
.catch(alert);
},
serializeFieldgroups(platform, layout: PlatformLayout) {
const styleDefinition = this.getPlatform(platform).styles[layout.style];
return Object.fromEntries(
Object.entries(layout.fieldgroups)
.map(([k, v]) => {
const fieldgroupDefinition = styleDefinition.fieldgroups.find(
(x) => x.identifier == k,
);
if (!fieldgroupDefinition) {
return;
}
if (fieldgroupDefinition.type == "placeholder") {
v = v as PlaceholderFieldGroupConfig;
v = {
...v,
entries: v.entries.filter(
(x) => x.type != "placeholder" || !!x.content,
),
};
}
return [k, v];
})
.filter((x) => !!x),
);
},
async serializePlatformLayout(platform, layout: PlatformLayout) {
const uploadedFiles = Object.fromEntries(
(
@@ -318,7 +344,7 @@ export function createWalletStore(config: {
style: layout.style,
file_settings: uploadedFiles,
layout: {
fieldgroups: layout.fieldgroups,
fieldgroups: this.serializeFieldgroups(platform, layout),
settings: layout.settings,
},
};
@@ -350,11 +376,16 @@ export function createWalletStore(config: {
body: JSON.stringify(serializedLayout),
},
)
.then((x) => x.json())
.catch((x) => alert(x))
.then((x) => {
if (!x.ok) {
throw new Error(`Response status: ${x.status}`);
}
return x.json();
})
.then((x) => {
this.parseServerLayout(x);
});
})
.catch((x) => alert(x));
},
},
});
+13 -4
View File
@@ -14,12 +14,17 @@ from django.utils.translation import gettext as _
from pretix.base.models import OrderPosition
from pretix.plugins.wallet.i18n import (
FormattingLocalizableString, GettextLocalizableString,
FormattingLocalizableString,
GettextLocalizableString,
MaybeTranslatedString,
)
from pretix.plugins.wallet.styles.base import (
FieldGroup, FieldGroupDisplay, PassStyle,
PlaceholderFieldEntry, TextFieldGroup, WalletPlatform,
FieldGroup,
FieldGroupDisplay,
PassStyle,
PlaceholderFieldEntry,
TextFieldGroup,
WalletPlatform,
)
from pretix.plugins.wallet.styles.settings import ImageSettingsField
@@ -326,7 +331,7 @@ class AppleWalletEventTicket(AppleWalletStyle):
max_entries=1,
display=FieldGroupDisplay.PLAIN,
context_args={"order_position"},
can_overflow=False
can_overflow=False,
),
TextFieldGroup(
identifier="header",
@@ -339,6 +344,7 @@ class AppleWalletEventTicket(AppleWalletStyle):
label=GettextLocalizableString.gettext("Admission"),
),
],
default_overflow="back",
),
TextFieldGroup(
identifier="primary",
@@ -353,6 +359,7 @@ class AppleWalletEventTicket(AppleWalletStyle):
description=_("These fields appear prominently featured on the pass."),
required=True,
context_args={"order_position"},
default_overflow="back",
),
TextFieldGroup(
identifier="secondary",
@@ -365,6 +372,7 @@ class AppleWalletEventTicket(AppleWalletStyle):
label=GettextLocalizableString.gettext("Product"),
)
],
default_overflow="back",
),
# TODO: validation of max field count if combined "Coupons, store cards, and generic passes
# with a square barcode can have a total of up to four secondary and auxiliary fields, combined."
@@ -390,6 +398,7 @@ class AppleWalletEventTicket(AppleWalletStyle):
label=GettextLocalizableString.gettext("To"),
),
],
default_overflow="back",
),
TextFieldGroup(
identifier="code",
+4
View File
@@ -176,6 +176,7 @@ class PlaceholderFieldGroup(FieldGroup):
str
] # what context arguments are available when rendering this fieldgroup
can_overflow: bool
default_overflow: str | None
def __init__(
self,
@@ -190,6 +191,7 @@ class PlaceholderFieldGroup(FieldGroup):
display=FieldGroupDisplay.WITH_LABEL,
context_args: set[str] | None = None,
can_overflow: bool = True,
default_overflow: str | None = None
):
super().__init__(identifier, name, description, required)
self.content_type = content_type
@@ -199,6 +201,7 @@ class PlaceholderFieldGroup(FieldGroup):
self.display = display
self.context_args = context_args or set()
self.can_overflow = can_overflow
self.default_overflow = default_overflow
if self.required and (self.min_entries is None or self.min_entries < 1):
self.min_entries = 1
@@ -224,6 +227,7 @@ class PlaceholderFieldGroup(FieldGroup):
"overflows": self.overflows(
remaining_fields, context, self.available_placeholders(context)
),
"default_overflow": self.default_overflow
}
def available_placeholders(self, context):
@@ -142,12 +142,14 @@ class Image(dict):
)
class GoogleWalletObjectMixin:
locales: set[str]
default_locale: str
class BaseGoogleWalletObject:
resource: Resource
id: str
data: dict
locales: set[str]
default_locale: str
def _localized_string(self, string: MaybeTranslatedString):
return localized_string(string, self.locales, self.default_locale)
@@ -171,7 +173,9 @@ class GoogleWalletObjectMixin:
return self.data
class EventTicketClass(GoogleWalletObjectMixin):
class EventTicketClass(BaseGoogleWalletObject):
resource = Resource.EVENT_TICKET_CLASS
def __init__(
self,
issuer_name: str,
@@ -279,7 +283,9 @@ class EventTicketClass(GoogleWalletObjectMixin):
)
class EventTicketObject(GoogleWalletObjectMixin):
class EventTicketObject(BaseGoogleWalletObject):
resource = Resource.EVENT_TICKET_OBJECT
def __init__(
self,
object_id: str,
@@ -362,7 +368,7 @@ class ButtonJWT(dict):
self,
issuer,
origins,
payload: dict[str, list[GoogleWalletObjectMixin]],
payload: dict[str, list[BaseGoogleWalletObject]],
precreated=True,
):
serialized_payload = {}
+8 -8
View File
@@ -45,7 +45,7 @@ from .forms import CertificateFileField, validate_rsa_privkey
from .models import GoogleWalletInstance, WalletPlatformLayout
from .styles.apple import ApplePlatform
from .styles.google import GooglePlatform
from .styles.google_wallet import ButtonJWT, Comms, Resource
from .styles.google_wallet import ButtonJWT, Comms, BaseGoogleWalletObject
logger = logging.getLogger("pretix.plugins.wallet")
@@ -167,24 +167,24 @@ class GoogleWalletTicketOutput(WalletOutput):
json.loads(self.event.settings.get("wallet_google_credentials").read())
)
def put_item_cached(self, resource: Resource, object):
def put_item_cached(self, object: BaseGoogleWalletObject):
with transaction.atomic():
instance, created = GoogleWalletInstance.objects.get_or_create(
event=self.event,
resource=resource,
resource=object.resource,
identifier=object.id,
defaults={"data": object.data},
)
if created or instance.data != object.data:
result = self.comms.put_item(resource, object.id, object.data)
result = self.comms.put_item(object.resource, object.id, object.data)
instance.data = object.data
instance.save(update_fields=["data"])
return result
def generate(self, position):
class_object, ticket_object = self.get_layout(position).generate(position)
self.put_item_cached(Resource.EVENT_TICKET_CLASS, class_object)
self.put_item_cached(Resource.EVENT_TICKET_OBJECT, ticket_object)
self.put_item_cached(class_object)
self.put_item_cached(ticket_object)
generated_jwt = self.comms.sign_jwt(
ButtonJWT(
@@ -209,9 +209,9 @@ class GoogleWalletTicketOutput(WalletOutput):
ticket_objects.append(ticket_object)
for co in dedup(class_objects):
self.put_item_cached(Resource.EVENT_TICKET_CLASS, co)
self.put_item_cached(co)
for to in dedup(ticket_objects):
self.put_item_cached(Resource.EVENT_TICKET_OBJECT, to)
self.put_item_cached(to)
generated_jwt = self.comms.sign_jwt(
ButtonJWT(