@lilaquadrat/design-core 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -3
- package/html/index.server.html +1 -8
- package/package.json +54 -54
- package/src/client-entry.ts +8 -8
- package/src/components/partials/error.partial.vue +19 -19
- package/src/components/partials/main-components.partial.vue +75 -70
- package/src/components/partials/qrcode.partial.vue +8 -8
- package/src/functions/AuthProviderFactory.ts +30 -0
- package/src/functions/PaymenyProviderFactory.ts +11 -11
- package/src/functions/auth0.provider.ts +75 -0
- package/src/functions/keycloak.provider.ts +228 -0
- package/src/functions/lila-dom.ts +50 -50
- package/src/functions/shopify.provider.ts +176 -154
- package/src/functions/stripe.provider.ts +120 -108
- package/src/globals.d.ts +1 -2
- package/src/index.ts +9 -7
- package/src/interfaces/AuthCallbackResult.interface.ts +5 -0
- package/src/interfaces/AuthConfig.interface.ts +13 -0
- package/src/interfaces/AuthProvider.interface.ts +15 -0
- package/src/interfaces/FrontendConfig.interface.ts +11 -40
- package/src/interfaces/GenericEvents.interface.ts +1 -1
- package/src/interfaces/IdTokenExtended.interface.ts +13 -4
- package/src/interfaces/PaymentProvider.interface.ts +2 -2
- package/src/interfaces/RenderOptions.interface.ts +12 -0
- package/src/libs/ActionNotice.ts +125 -125
- package/src/libs/Models.class.ts +219 -221
- package/src/main.ts +41 -36
- package/src/mixins/createCookieString.ts +50 -36
- package/src/mixins/createModelDeclaration.ts +22 -19
- package/src/mixins/createRouter.ts +12 -12
- package/src/mixins/date.ts +4 -2
- package/src/mixins/formatSize.ts +5 -5
- package/src/mixins/getAnchor.ts +1 -1
- package/src/mixins/getRoutes.ts +13 -25
- package/src/mixins/hasSlotContent.ts +22 -16
- package/src/mixins/hooks.ts +101 -60
- package/src/mixins/loadComponents.ts +60 -58
- package/src/mixins/logger.ts +17 -13
- package/src/mixins/replaceVariables.ts +10 -8
- package/src/mixins/scroll.ts +61 -45
- package/src/models/Address.model.ts +7 -7
- package/src/models/Contact.model.ts +14 -14
- package/src/plugins/analytics.ts +198 -0
- package/src/plugins/auth.ts +74 -60
- package/src/plugins/currency.ts +10 -10
- package/src/plugins/events.ts +101 -97
- package/src/plugins/filters.ts +21 -18
- package/src/plugins/replacer.ts +7 -6
- package/src/plugins/signupFlow.ts +45 -43
- package/src/plugins/traceable.ts +28 -26
- package/src/plugins/translations.ts +9 -9
- package/src/plugins/youtube.ts +39 -34
- package/src/routes.ts +108 -108
- package/src/server-entry.ts +75 -77
- package/src/stores/calls.store.ts +14 -14
- package/src/stores/cart.store.ts +116 -107
- package/src/stores/content.store.ts +87 -45
- package/src/stores/editor.store.ts +16 -16
- package/src/stores/files.store.ts +72 -72
- package/src/stores/main.store.ts +155 -109
- package/src/stores/user.store.ts +72 -68
- package/src/translations/de.ts +127 -127
- package/src/views/content.view.vue +81 -143
- package/src/views/download.view.vue +25 -23
- package/src/views/editor.view.vue +150 -125
- package/src/views/login.view.vue +35 -36
- package/src/views/signup-account.view.vue +14 -14
- package/tooling/cypress/config.ts +68 -54
- package/tooling/cypress/manifest-utils.mjs +34 -22
- package/tooling/cypress/run-parallel.mjs +41 -35
- package/tooling/cypress/support/commands.ts +458 -300
- package/tooling/eslint.config.js +1 -223
- package/tooling/preview.plugin.js +132 -0
- package/tooling/ssr-test/index.mjs +205 -203
- package/tooling/vite.d.ts +36 -0
- package/tooling/vite.js +234 -0
- package/src/interfaces/EditorConfiguration.interface.ts +0 -15
- package/tooling/preview.plugin.ts +0 -134
- package/tooling/stylelint.config.mjs +0 -24
- package/tooling/vite.ts +0 -260
package/src/translations/de.ts
CHANGED
|
@@ -8,131 +8,131 @@
|
|
|
8
8
|
* addMessages() - see plugins/translations.
|
|
9
9
|
*/
|
|
10
10
|
export default {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
11
|
+
'home': 'Home',
|
|
12
|
+
'validation-error-type-number': 'muss eine Zahl sein',
|
|
13
|
+
'validation-error-type-string': 'muss Text sein',
|
|
14
|
+
'validation-error-minLength': 'muss mindestens {0} Zeichen lang sein',
|
|
15
|
+
'validation-error-maxLength': 'darf maximal {0} Zeichen lang sein',
|
|
16
|
+
'validation-error-additionalProperties': 'Das zusätzliche Attribut {0} ist nicht erlaubt',
|
|
17
|
+
'validation-error-maxItems': 'darf maximal {0} Elemente besitzen',
|
|
18
|
+
'validation-error-minItems': 'muss mindestens {0} Elemente besitzen',
|
|
19
|
+
'validation-error-contains': 'muss mindestens {0} valide(s) Element(e) besitzen',
|
|
20
|
+
'validation-error-required': 'muss gesetzt sein',
|
|
21
|
+
'validation-error-accepted': 'Vereinbarungen müssen akzeptiert werden',
|
|
22
|
+
'validation-error-invalidId': 'ist keine valide ID',
|
|
23
|
+
'validation-error-USER_ALREADY_CONNECTED': 'Der Benutzer ist bereits mit einem Account verbunden',
|
|
24
|
+
'city': 'Stadt',
|
|
25
|
+
'zipcode': 'Postleitzahl',
|
|
26
|
+
'street & number': 'Straße & Hausnummer',
|
|
27
|
+
'street': 'Straße',
|
|
28
|
+
'streetnumber': 'Hausnummer',
|
|
29
|
+
'prename': 'Vorname',
|
|
30
|
+
'name': 'Name',
|
|
31
|
+
'country': 'Land',
|
|
32
|
+
'country-aut': 'Österreich',
|
|
33
|
+
'country-che': 'Schweiz',
|
|
34
|
+
'country-deu': 'Deutschland',
|
|
35
|
+
'email': 'E-Mail',
|
|
36
|
+
'phone': 'Telefon',
|
|
37
|
+
'personal': 'Persönliche Daten',
|
|
38
|
+
'address': 'Adresse',
|
|
39
|
+
'addressAddition': 'Adresszusatz',
|
|
40
|
+
'contact': 'Kontakt',
|
|
41
|
+
'price_with_tax': 'inkl. {0}% MwSt.',
|
|
42
|
+
'category': 'Kategorie',
|
|
43
|
+
'message': 'Nachricht',
|
|
44
|
+
'order with payment': 'Zahlungspflichtig bestellen',
|
|
45
|
+
'back to the form': 'Zurück zum Formular',
|
|
46
|
+
'not available': 'nicht verfügbar',
|
|
47
|
+
'no charge': 'kostenlos',
|
|
48
|
+
'address addition': 'Adresszusatz',
|
|
49
|
+
'address search': 'Adresssuche',
|
|
50
|
+
'no matching addresses': 'Keine passende Adresse gefunden',
|
|
51
|
+
'provide at least your street and housenumber to find your address. city and zipcode increase accuracy.': 'Bitte geben Sie mindestens Ihre Straße und Hausnummer an, um Ihre Adresse zu finden. Stadt und Postleitzahl erhöhen die Genauigkeit.',
|
|
52
|
+
'type your street and number': 'Strasse und Hausnummer',
|
|
53
|
+
'validation-error-LIST_CANNOT_JOIN': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
54
|
+
'validation-error-LIST_NOT_FOUND': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
55
|
+
'validation-error-LIST_NO_SPOT_AVAILABLE': 'Es ist keine weiteren Plätze verfügbar.',
|
|
56
|
+
'validation-error-LIST_UNIQUE_CUSTOMER_CONFIRMED': 'Die maximale Anzahl wurde erreicht.',
|
|
57
|
+
'validation-error-EMAIL_INVALID': 'Bitte überprüfe deine E-Mail Adresse',
|
|
58
|
+
'LIST_CANNOT_JOIN_reservation': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
59
|
+
'LIST_UNIQUE_CUSTOMER_CONFIRMED_reservation': 'Sie sind bereits für eine Reservierung vorgemerkt.',
|
|
60
|
+
'LIST_NOT_FOUND_reservation': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
61
|
+
'LIST_NO_SPOT_AVAILABLE_reservation': 'Leider sind keine Plätze mehr verfügbar.',
|
|
62
|
+
'LIST_CANNOT_JOIN_contact': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
63
|
+
'LIST_UNIQUE_CUSTOMER_CONFIRMED_contact': 'Sie haben bereits die maximale Anzahl an Nachrichten gesendet.',
|
|
64
|
+
'LIST_NOT_FOUND_contact': 'Es ist leider ein Fehler aufgetreten. Bitte versuchen Sie es später erneut.',
|
|
65
|
+
'LIST_NO_SPOT_AVAILABLE_contact': 'Die maximale Anzahl an Nachrichten wurde erreicht.',
|
|
66
|
+
'LIST_CATEGORY_LIMITED_AVAILABILITY_SINGULAR': 'Nur einmalig verfügbar',
|
|
67
|
+
'LIST_CATEGORY_LIMITED_AVAILABILITY_PLURAL': 'Limitiert auf {0} Plätze.',
|
|
68
|
+
'LIST_CATEGORY_LIMITED_AVAILABILITY': 'Nur einmalig verfügbar | Limitiert auf {0} Plätze.',
|
|
69
|
+
'LIST_LIMITED_AVAILABILITY_SINGULAR': 'Für diese Veranstaltung ist maximal ein Platz verfügbar.',
|
|
70
|
+
'LIST_LIMITED_AVAILABILITY_PLURAL': 'Für diese Veranstaltung sind maximal {0} Plätze verfügbar.',
|
|
71
|
+
'LIST_LIMITED_AVAILABILITY': 'Für diese Veranstaltung ist maximal ein Platz verfügbar. | Für diese Veranstaltung sind maximal {0} Plätze verfügbar.',
|
|
72
|
+
'LIST_LIMITED_AVAILABILITY_STATE': 'Für diese Veranstaltung sind noch {0} von {1} Plätze verfügbar.',
|
|
73
|
+
'LIST_CATEGORY_LAST_CHANCE_PERCENT': 'Mehr als {0}% gebucht',
|
|
74
|
+
'LIST_CATEGORY_LAST_CHANCE_SINGULAR': 'Nur noch {0} Platz verfügbar',
|
|
75
|
+
'LIST_CATEGORY_LAST_CHANCE_PLURAL': 'Nur noch {0} Plätze verfügbar',
|
|
76
|
+
'LIST_CATEGORY_LAST_CHANCE': 'Nur noch {0} Platz verfügbar | Nur noch {0} Plätze verfügbar',
|
|
77
|
+
'LIST_CATEGORY_SOLD_OUT': 'AUSVERKAUFT',
|
|
78
|
+
'LIST_SOLD_OUT': 'Es sind keine weiteren Plätze verfügbar',
|
|
79
|
+
'EMAIL_INVALID_contact': 'Bitte überprüfe deine E-Mail Adresse',
|
|
80
|
+
'EMAIL_INVALID_reservation': 'Bitte überprüfe deine E-Mail Adresse',
|
|
81
|
+
'EMAIL_INVALID_content': 'Bitte überprüfe deine E-Mail Adresse',
|
|
82
|
+
'euro': '€',
|
|
83
|
+
'required': 'erforderlich',
|
|
84
|
+
'disabled': 'deaktiviert',
|
|
85
|
+
'loading': 'wird geladen',
|
|
86
|
+
'Something went wrong': 'Hier ist etwas schief gelaufen',
|
|
87
|
+
'The content is missing': 'Der Inhalt wurde nicht gefunden',
|
|
88
|
+
'CONTENT_NOT_FOUND': 'Inhalt wurde nicht gefunden',
|
|
89
|
+
'CONTENT_LOADING': 'Wird geladen',
|
|
90
|
+
'customerId': 'Kunden ID',
|
|
91
|
+
'connect-to-user': 'Account verbinden',
|
|
92
|
+
'confirm-email': 'E-Mail Adresse bestätigen',
|
|
93
|
+
'signup-step-register': 'Registrierung',
|
|
94
|
+
'signup-step-account': 'Konto erstellen',
|
|
95
|
+
'signup-step-connect': 'Account verbinden',
|
|
96
|
+
'signup-step-verify': 'E-Mail bestätigen',
|
|
97
|
+
'ORDER_SUCCESS_TITLE': 'Vielen Dank für deinen Kauf',
|
|
98
|
+
'INVOICE_NOT_YET_READY_TITLE': 'Deine Rechnung ist noch nicht verfügbar.',
|
|
99
|
+
'INVOICE_NOT_YET_READY_DESCRIPTION': 'Du kannst diese Seite neu laden um den Status zu aktualisieren.',
|
|
100
|
+
'INVOICE_DOWNLOAD': 'Rechnung herunterladen',
|
|
101
|
+
'ORDER_ERROR_TITLE': 'Ein Fehler ist aufgetreten',
|
|
102
|
+
'ORDER_ERROR_DESCRIPTION': 'Deine Bestellung konnte leider nicht gefunden werden. Bitte versuche es später erneut.',
|
|
103
|
+
'confirmationCode': 'Bestätigungscode',
|
|
104
|
+
'EMAIL_CONFIRMATION_FAILED': 'E-Mail Adresse konnte nicht bestaetigt werden.',
|
|
105
|
+
'validation-error-EMAIL_CONFIRMATION_FAILED': 'E-Mail Adresse konnte nicht bestaetigt werden.',
|
|
106
|
+
'CONFIRM_BUTTON': 'Aktion bestätigen',
|
|
107
|
+
'files-add': 'Dateien hinzufügen',
|
|
108
|
+
'files-start-upload': 'Upload starten',
|
|
109
|
+
'files-clear-finished': 'Abgeschlossene entfernen',
|
|
110
|
+
'files-remove': 'Entfernen',
|
|
111
|
+
'files-delete': 'Löschen',
|
|
112
|
+
'files-download': 'Herunterladen',
|
|
113
|
+
'files-uploaded-at': 'Hochgeladen',
|
|
114
|
+
'files-loading': 'Dateien werden geladen...',
|
|
115
|
+
'files-empty': 'Keine Dateien vorhanden',
|
|
116
|
+
'files-list': 'Dateien',
|
|
117
|
+
'files-state-pending': 'Wartet',
|
|
118
|
+
'files-state-creating': 'Erstelle...',
|
|
119
|
+
'files-state-processing': 'Verarbeitet',
|
|
120
|
+
'files-state-uploading': 'Lädt hoch',
|
|
121
|
+
'files-state-done': 'Fertig',
|
|
122
|
+
'files-state-error': 'Fehler',
|
|
123
|
+
'files-asset': 'Asset',
|
|
124
|
+
'files-max-size': 'Max. Dateigröße',
|
|
125
|
+
'files-max-count': 'Max. Anzahl',
|
|
126
|
+
'files-allowed-types': 'Erlaubte Dateitypen',
|
|
127
|
+
'files-error-mime': 'Dateityp nicht erlaubt',
|
|
128
|
+
'files-error-too-large': 'Datei überschreitet maximale Größe',
|
|
129
|
+
'files-error-max-count': 'Maximale Anzahl Dateien erreicht',
|
|
130
|
+
'files-error-no-asset': 'Asset auswählen vor dem Hochladen',
|
|
131
|
+
'files-error-select-structure': 'Bitte zuerst eine Kategorie auswählen',
|
|
132
|
+
'files-select-structure': 'Kategorie auswählen',
|
|
133
|
+
'files-category-all': 'Alle Dateien',
|
|
134
|
+
'files-download-start': 'Download starten',
|
|
135
|
+
'files-error-no-url': 'Download-URL konnte nicht erstellt werden',
|
|
136
|
+
'FILE_LIMIT_EXCEEDED': 'Maximale Anzahl Dateien überschritten',
|
|
137
|
+
'UPLOAD_FAILED': 'Upload fehlgeschlagen',
|
|
138
138
|
};
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed, ref, watch } from 'vue';
|
|
2
|
+
import { computed, onBeforeMount, onBeforeUnmount, onServerPrefetch, ref, watch } from 'vue';
|
|
3
3
|
import { distributeGenericData, generateDataWithContent, hardCopy, prepareContent } from '@lilaquadrat/frontend/content';
|
|
4
4
|
import type { BasicData, Content, ContentWithPositions, GenericData } from '@lilaquadrat/interfaces';
|
|
5
5
|
import useMainStore from '../stores/main.store';
|
|
6
6
|
import { useRoute } from 'vue-router';
|
|
7
|
-
import {
|
|
8
|
-
import type { SDKResponse } from '@lilaquadrat/sdk';
|
|
7
|
+
import { isAxiosError } from 'axios';
|
|
9
8
|
import useUserStore from '../stores/user.store';
|
|
10
|
-
import { onServerPrefetch } from 'vue';
|
|
11
9
|
import useContentStore from '../stores/content.store';
|
|
12
10
|
import { HelpersPlugin } from '../plugins/filters';
|
|
13
11
|
|
|
@@ -16,204 +14,144 @@ const userStore = useUserStore();
|
|
|
16
14
|
const mainStore = useMainStore();
|
|
17
15
|
const contentStore = useContentStore();
|
|
18
16
|
const dataMerged = ref<ContentWithPositions>();
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
const error = ref<boolean>(false);
|
|
17
|
+
const status = ref(0);
|
|
18
|
+
let requestId = 0;
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
watch(() => userStore.locked, () => getContent());
|
|
25
|
-
onBeforeMount(async () => await getContent());
|
|
26
|
-
onServerPrefetch(() => getStoreContent(HelpersPlugin.getFilename(contentType.value, route.path)));
|
|
27
|
-
|
|
28
|
-
const linkMode = computed(() => {
|
|
29
|
-
|
|
30
|
-
if(mainStore.config?.dynamic !== true) return 'link';
|
|
31
|
-
|
|
32
|
-
return undefined
|
|
33
|
-
|
|
34
|
-
});
|
|
20
|
+
const linkMode = computed(() => mainStore.dynamic === true ? undefined : 'link');
|
|
35
21
|
const contentType = computed(() => route.meta.contentType as 'public' | 'members');
|
|
36
|
-
const
|
|
22
|
+
const filename = computed(() => HelpersPlugin.getFilename(contentType.value, route.path));
|
|
23
|
+
const isLocked = computed(() => contentType.value === 'members' && Boolean(userStore.locked));
|
|
24
|
+
const error = computed(() => status.value !== 0 && status.value !== 200);
|
|
37
25
|
const hint = computed(() => {
|
|
38
26
|
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if(isLocked.value) {
|
|
27
|
+
if(status.value === 404) return 'error-404';
|
|
28
|
+
return isLocked.value ? `error-${userStore.locked}-${contentType.value}` : undefined;
|
|
44
29
|
|
|
45
|
-
|
|
30
|
+
});
|
|
46
31
|
|
|
47
|
-
|
|
32
|
+
watch([() => route.path, contentType, () => userStore.locked], getContent);
|
|
33
|
+
onBeforeMount(getContent);
|
|
34
|
+
onServerPrefetch(() => {
|
|
48
35
|
|
|
49
|
-
|
|
36
|
+
if(isLocked.value) status.value = 403;
|
|
37
|
+
else useStoreContent();
|
|
50
38
|
|
|
51
39
|
});
|
|
40
|
+
onBeforeUnmount(() => { requestId++; });
|
|
52
41
|
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
const storeContent = mainStore.data;
|
|
56
|
-
const storeLayout = mainStore.layout;
|
|
42
|
+
function useStoreContent(): boolean {
|
|
57
43
|
|
|
58
|
-
|
|
44
|
+
const storeContent = contentStore.content;
|
|
45
|
+
if(!storeContent) return false;
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if(storeContent && (storeContent.settings?.filename?.includes(filename) || storeContent.target === 'mail' || filename === '__pdf')) {
|
|
65
|
-
|
|
66
|
-
dataMerged.value = mergeContent(storeContent, storeLayout);
|
|
67
|
-
loading.value = 200;
|
|
68
|
-
error.value = false;
|
|
47
|
+
// Published mail and PDF renders do not need a matching page filename.
|
|
48
|
+
const matches = storeContent.settings?.filename?.includes(filename.value)
|
|
49
|
+
|| storeContent.target === 'mail' || filename.value === '__pdf';
|
|
50
|
+
if(!matches) return false;
|
|
69
51
|
|
|
70
|
-
|
|
52
|
+
renderContent(storeContent, contentStore.layout);
|
|
71
53
|
return true;
|
|
72
|
-
|
|
73
|
-
} else {
|
|
74
|
-
|
|
75
|
-
dataMerged.value = undefined;
|
|
76
|
-
return false;
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
54
|
}
|
|
81
55
|
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
contentStore.setContext({
|
|
85
|
-
sitetitle : mainStore.data?.settings?.title,
|
|
86
|
-
description: mainStore.data?.settings?.description,
|
|
87
|
-
})
|
|
56
|
+
function renderContent(content: BasicData<Content>, layout?: BasicData<Content>) {
|
|
88
57
|
|
|
58
|
+
dataMerged.value = mergeContent(content, layout);
|
|
59
|
+
contentStore.content = content;
|
|
60
|
+
contentStore.layout = layout;
|
|
61
|
+
contentStore.setContext({
|
|
62
|
+
sitetitle: content.settings?.title,
|
|
63
|
+
description: content.settings?.description,
|
|
64
|
+
});
|
|
65
|
+
status.value = 200;
|
|
89
66
|
}
|
|
90
67
|
|
|
91
|
-
async function getContent
|
|
92
|
-
|
|
93
|
-
let content: SDKResponse<BasicData<Content>> | undefined;
|
|
94
|
-
|
|
95
|
-
if(isLocked.value) {
|
|
96
|
-
|
|
97
|
-
error.value = true;
|
|
98
|
-
loading.value = 403;
|
|
99
|
-
return;
|
|
68
|
+
async function getContent() {
|
|
100
69
|
|
|
101
|
-
|
|
70
|
+
const currentRequest = ++requestId;
|
|
71
|
+
const type = contentType.value;
|
|
102
72
|
|
|
103
|
-
|
|
73
|
+
if(isLocked.value) {
|
|
104
74
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
* to avoid fetching it again from the server
|
|
108
|
-
*/
|
|
75
|
+
status.value = 403;
|
|
76
|
+
return;
|
|
109
77
|
|
|
110
|
-
|
|
78
|
+
}
|
|
111
79
|
|
|
112
|
-
|
|
80
|
+
try {
|
|
113
81
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
try {
|
|
118
|
-
|
|
119
|
-
content = await mainStore.getContent({filename}, contentType.value) as SDKResponse<BasicData<Content>>;
|
|
120
|
-
|
|
121
|
-
} catch (e) {
|
|
122
|
-
|
|
123
|
-
console.error(error);
|
|
124
|
-
loading.value = e.response.status;
|
|
82
|
+
// Hydration reuses the server's page and layout without fetching either again.
|
|
83
|
+
if(useStoreContent()) return;
|
|
125
84
|
|
|
126
|
-
|
|
85
|
+
// Keep the previous merge mounted until the next page and layout are ready.
|
|
86
|
+
status.value = 0;
|
|
87
|
+
const response = await mainStore.getContent({ filename: filename.value }, type);
|
|
88
|
+
if(currentRequest !== requestId) return;
|
|
127
89
|
|
|
128
|
-
|
|
90
|
+
if(response.status !== 200 || !response.data) {
|
|
129
91
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
updateContext();
|
|
133
|
-
|
|
134
|
-
if(loading.value === 200) {
|
|
92
|
+
status.value = response.status === 204 || response.status === 200 ? 404 : response.status || 404;
|
|
93
|
+
return;
|
|
135
94
|
|
|
136
|
-
|
|
95
|
+
}
|
|
137
96
|
|
|
138
|
-
|
|
97
|
+
const content = response.data;
|
|
98
|
+
const layoutResponse = await getLayout(content, type);
|
|
99
|
+
if(currentRequest !== requestId) return;
|
|
139
100
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
101
|
+
// A page remains valid when its optional layout has not been published.
|
|
102
|
+
const layoutMissing = layoutResponse?.status === 204 || layoutResponse?.status === 404;
|
|
103
|
+
if(layoutResponse && !layoutMissing && (layoutResponse.status !== 200 || !layoutResponse.data)) {
|
|
143
104
|
|
|
144
|
-
|
|
105
|
+
status.value = layoutResponse.status === 200 ? 404 : layoutResponse.status || 404;
|
|
106
|
+
return;
|
|
145
107
|
|
|
146
|
-
|
|
147
|
-
mainStore.layout = layout.value.data;
|
|
108
|
+
}
|
|
148
109
|
|
|
149
|
-
|
|
110
|
+
renderContent(content, layoutMissing ? undefined : layoutResponse?.data);
|
|
150
111
|
|
|
151
|
-
|
|
152
|
-
layout.value = undefined;
|
|
112
|
+
} catch (cause: unknown) {
|
|
153
113
|
|
|
154
|
-
|
|
114
|
+
if(currentRequest !== requestId) return;
|
|
115
|
+
console.error(cause);
|
|
116
|
+
status.value = isAxiosError(cause) ? cause.response?.status ?? 400 : 400;
|
|
155
117
|
|
|
156
118
|
}
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if ([400, 401, 403].includes(loading.value)) {
|
|
161
|
-
|
|
162
|
-
error.value = true;
|
|
163
|
-
|
|
164
|
-
} else if ([204, 404].includes(loading.value) || !loading.value) {
|
|
165
|
-
|
|
166
|
-
error.value = true;
|
|
167
|
-
loading.value = 404;
|
|
119
|
+
}
|
|
168
120
|
|
|
169
|
-
|
|
121
|
+
async function getLayout(content: BasicData<Content>, type: 'public' | 'members') {
|
|
170
122
|
|
|
171
|
-
|
|
123
|
+
// An explicitly assigned layout takes precedence over the dynamic default.
|
|
124
|
+
if(content.settings?.useLayout) {
|
|
172
125
|
|
|
173
|
-
|
|
126
|
+
return mainStore.getContent({ internalId: content.settings.useLayout.toString() }, type);
|
|
174
127
|
|
|
175
|
-
|
|
128
|
+
}
|
|
176
129
|
|
|
177
|
-
|
|
130
|
+
if(mainStore.dynamic === true) {
|
|
178
131
|
|
|
179
|
-
|
|
132
|
+
return mainStore.getContent({ id: `${type}-layout` }, type);
|
|
180
133
|
|
|
134
|
+
}
|
|
181
135
|
}
|
|
182
136
|
|
|
183
|
-
function mergeContent
|
|
137
|
+
function mergeContent(baseContent: BasicData<Content>, layout?: BasicData<Content>) {
|
|
184
138
|
|
|
185
|
-
if(baseContent) {
|
|
186
|
-
|
|
187
139
|
const safeData = hardCopy(baseContent);
|
|
188
140
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* content without generic data is the normal case for a static page, and
|
|
193
|
-
* generateDataWithContent reads Object.keys of what it is given - so it
|
|
194
|
-
* throws on undefined instead of returning nothing
|
|
195
|
-
*/
|
|
196
|
-
if(safeData.genericData) {
|
|
141
|
+
// Static pages commonly have no generic data; generation requires an object.
|
|
142
|
+
if(safeData.modules && safeData.genericData) {
|
|
197
143
|
|
|
198
144
|
distributeGenericData(safeData.modules, generateDataWithContent(safeData.genericData as GenericData));
|
|
199
|
-
|
|
200
|
-
}
|
|
201
|
-
|
|
202
145
|
}
|
|
203
146
|
|
|
204
147
|
return prepareContent(safeData, layout);
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
return prepareContent({})
|
|
209
|
-
|
|
210
|
-
}
|
|
148
|
+
}
|
|
211
149
|
|
|
212
150
|
</script>
|
|
213
151
|
|
|
214
152
|
<template>
|
|
215
153
|
<article class="content-screen screen">
|
|
216
|
-
<lila-error-partial v-if="error" :status="
|
|
154
|
+
<lila-error-partial v-if="error" :status="status" :hint="hint" :type="contentType" />
|
|
217
155
|
<lila-content-module v-if="dataMerged && !error" :link-mode="linkMode" :content="dataMerged" />
|
|
218
156
|
</article>
|
|
219
|
-
</template>
|
|
157
|
+
</template>
|