Compare commits

...

2 Commits

Author SHA1 Message Date
9d58febf4d version two
Some checks failed
deploy to production / deploy (push) Failing after 31s
2023-11-12 11:45:32 +00:00
92ca030e6c first version 2023-11-12 10:02:26 +00:00
36 changed files with 1089 additions and 465 deletions

View File

@ -85,9 +85,9 @@ jobs:
# docker compose -p ${GITHUB_REF_NAME}-${GITHUB_REPOSITORY_NAME}-${GITHUB_REPOSITORY_OWNER} up -d --build --remove-orphans
- name: deploy
if: github.ref == 'refs/heads/master'
#if: github.ref == 'refs/heads/master'
env:
RSYNC_USER: "fontis_rsync_master"
RSYNC_PASS: ${{ secrets.rsync_master }}
#RSYNC_USER: "fontis_rsync_master"
# RSYNC_PASS: ${{ secrets.rsync_master }}
run: |
scripts/deploy.sh ftp1.webmakers.de $RSYNC_USER $RSYNC_PASS

View File

@ -11,6 +11,12 @@ meta:
- type: table
columns:
- source: path
name: Pfad
- source: pageTitle
name: Titel
- source: active
name: Aktiv
tablist:
activeTab: site
tabs:
@ -18,17 +24,95 @@ meta:
label: Allgemein
subFields:
- source: path
- source: pageTitle
- source: type
- source: active
- name: teaser
label: Teaser
label: Homepage Seitenteaser
subFields:
- source: teaser
- name: personPreview
label: Personenvorschau
subFields:
- source: personType
- source: personPreview
- name: jobOffer
label: Job Angebote
subFields:
- source: jobOffer
- name: site
label: Seite
subFields:
- source: rows
subNavigation:
- name: seite
label:
de: Seiten
en: pages
muiIcon: book-open-page-variant
defaultSort:
field: "pfad"
order: "ASC"
views:
- type: table
columns:
- source: path
name: Pfad
- source: pageTitle
name: Titel
- source: active
name: Aktiv
filter:
type: page
- name: teamMembers
label:
de: Teammitglieder
en: Team members
muiIcon: book-open-page-variant
defaultSort:
field: "pfad"
order: "ASC"
views:
- type: table
columns:
- source: path
name: Pfad
- source: pageTitle
name: Titel
- source: active
name: Aktiv
filter:
type: teamMembers
- name: jobOffers
label:
de: Stellenanzeigen
en: Job offers
muiIcon: book-open-page-variant
defaultSort:
field: "pfad"
order: "ASC"
views:
- type: table
columns:
- source: path
name: Pfad
- source: pageTitle
name: Titel
- source: active
name: Aktiv
filter:
type: jobOffers
imageFilter:
xs:
- fit: true
@ -86,15 +170,165 @@ fields:
meta:
label: Pfad
helperText: "Ein Pfad sollte mit einem / starten und ohne eins enden."
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- type: boolean
name: active
meta:
label: Aktiv
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- type: string
name: type
meta:
label: Typ
widget: select
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
choices:
- name: Seite
id: page
- name: Teammitglieder
id: teamMembers
- name: Stellenanzeigen
id: jobOffers
- name: pageTitle
type: string
meta:
label: Titel der Seite
helperText: "Dieser Titel wird in der Seite als h1 angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- name: personType
type: string
meta:
label: Typ
widget: select
choices:
- name: Chef
id: chef
- name: Mitarbeiter
id: employee
- name: personPreview
type: object
meta:
label: Personenvorschau
subFields:
- name: initialImage
type: string
meta:
label: Bild
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
dependsOn:
eval: $.personType == 'chef'
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: hoverImage
type: string
meta:
label: Bild beim Hover
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
dependsOn:
eval: $.personType == 'chef'
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: name
type: string
meta:
label: Name
- !include fields/teaserHomepage.yml
- name: jobOffer
type: object
meta:
label: Job Angebote
subFields:
- name: title
type: string
meta:
label: Titel
- name: text
type: string
meta:
widget: richtext
label: Text
- name: emailButton
type: boolean
meta:
label: E-Mail Button Anzeigen
- name: emailSubject
type: string
meta:
label: E-Mail default Betreff
dependsOn:
eval: $parent.emailButton == true
- name: rows
type: object[]
meta:
label: Zeilen
widget: containerLessObjectArray
widget: grid
metaElements:
- source: backgroundImage
- source: noBottomMargin
- source: noTopMargin
- source: flexWrapNormal
- source: twoToThree
- source: nextPage
folding:
force: true
subFields:
- !include fields/row.yml
subFields: !include fieldLists/row.yml

View File

@ -1,11 +1,32 @@
- name: icon
type: file
type: string
meta:
label: Icon
helperText: "Das Icon wird in der Box angezeigt."
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- name: text
type: string
meta:
label: Text
helperText: "Der Text wird in der Box angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"

View File

@ -1,8 +1,15 @@
- name: image
type: file
type: string
meta:
label: Kartenausschnitt
helperText: "Der Kartenausschnitt wird als Hintergrundbild angezeigt."
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
render:
defaultCollectionViews: true
- name: title
type: string

View File

@ -7,11 +7,8 @@
- name: Bild
id: image
- name: Icons im Rechteck
id: iconCycleSquare
- name: Icons im Kreis
id: iconCycleCircle
- name: Modul Import
id: moduleImport
- name: Text
id: text
@ -19,21 +16,12 @@
- name: Informationsbrett
id: infoBoard
- name: Weltkarte
id: worldCard
- name: Verschatelte Karte
id: nestedCard
- name: Top-Down
id: topDown
- name: Personenvorschau
id: personPreview
- name: Boxliste
id: boxlist
- name: Ausfahrbare Box
id: extendableBoxes
@ -43,9 +31,6 @@
- name: Icon block
id: iconBlocks
- name: Seitenlinks
id: pageLinkBlocks
- name: Netzwerk Veranstaltungen
id: networkEvents
@ -58,16 +43,30 @@
label: Netzwerkveranstaltungen
dependsOn:
eval: $parent.contentType == 'networkEvents'
widget: containerLessObjectArray
subFields:
- name: beginDate
type: date
meta:
label: Beginn
containerProps:
layout:
size:
default: "col-6"
small: "col-6"
large: "col-6"
- name: endDate
type: date
meta:
label: Ende
containerProps:
layout:
size:
default: "col-6"
small: "col-6"
large: "col-6"
- name: title
type: string
@ -75,9 +74,18 @@
label: Titel
- name: file
type: file
type: string
meta:
label: downloadDatei
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: publications
type: object[]
@ -85,6 +93,8 @@
label: Publikationen
dependsOn:
eval: $parent.contentType == 'publications'
widget: containerLessObjectArray
direction: row
subFields:
- name: content
type: string
@ -93,9 +103,18 @@
widget: richtext
- name: file
type: file
type: string
meta:
label: downloadDatei
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: iconBlocks
type: object[]
@ -103,11 +122,22 @@
label: Icon block
dependsOn:
eval: $parent.contentType == 'iconBlocks'
widget: containerLessObjectArray
direction: row
subFields:
- name: icon
type: file
type: string
meta:
label: Icon
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: bigText
type: string
meta:
@ -117,82 +147,64 @@
meta:
label: unterer Text
- name: pageLinkBlocks
type: object[]
meta:
label: Seitenlinks
dependsOn:
eval: $parent.contentType == 'pageLinkBlocks'
subFields:
- name: page
type: string
meta:
label: Seite
widget: select
choices:
endpoint: page
params:
sort: path
projection: navigation
mapping:
id: id
name: path
- name: name
type: string
meta:
label: Name
- name: rowNr
type: number
meta:
label: Zeilen Nr (0 Basiert)
- name: extendableRowNr
type: number
meta:
label: Ausfahrbare boxreihe (0 Basiert)
- name: image
type: file
type: string
meta:
label: Bild
dependsOn:
eval: $parent.contentType == 'image'
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: icons
type: object[]
meta:
label: Icons
helperText: "Für Personpreview xing und linkedin icons gedacht."
widget: containerLessObjectArray
direction: row
dependsOn:
eval: $parent.contentType == 'image'
subFields:
- name: icon
type: file
type: string
meta:
label: Icon
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: link
type: string
meta:
label: Link
- name: iconCycleSquare
type: object
- name: moduleImport
type: string
meta:
label: Icons im Rechteck
label: Modul Import
dependsOn:
eval: $parent.contentType == 'iconCycleSquare'
subFields: !include iconCycleSquare.yml
- name: iconCycleCircle
type: object
meta:
label: Icons im Kreis
dependsOn:
eval: $parent.contentType == 'iconCycleCircle'
subFields: !include iconCycleCircle.yml
eval: $parent.contentType == 'moduleImport'
widget: foreignKey
foreign:
collection: module
id: id
subNavigation: 0
render:
defaultCollectionViews: true
- name: text
type: string
@ -206,6 +218,7 @@
type: object
meta:
label: Informationsbrett
widget: containerLessObject
dependsOn:
eval: $parent.contentType == 'infoBoard'
subFields:
@ -223,36 +236,26 @@
helperText: "Dieser Text wird im Infobrett angezeigt."
- name: icon
type: file
type: string
meta:
label: Icon
helperText: "Das Icon wird im Infobrett angezeigt."
- name: worldCard
type: object
meta:
label: Weltkarte
dependsOn:
eval: $parent.contentType == 'worldCard'
subFields:
- name: row
type: object[]
meta:
label: Zeilen
subFields:
- name: cards
type: object[]
meta:
label: Karten
metaElements:
- verticalAlignment
- horizontalAlignment
subFields: !include cards.yml
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: nestedCard
type: object[]
meta:
label: Verschatelte Karte
widget: containerLessObjectArray
direction: row
dependsOn:
eval: $parent.contentType == 'nestedCard'
subFields:
@ -272,6 +275,7 @@
type: object
meta:
label: Top-Down
widget: containerLessObject
dependsOn:
eval: $parent.contentType == 'topDown'
subFields:
@ -279,110 +283,40 @@
type: object[]
meta:
label: Zeilen
widget: containerLessObjectArray
subFields:
- name: inital
type: string
meta:
label: Großbuchstabe
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- name: rest
type: string
meta:
label: Rest
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- name: description
type: string
meta:
label: Beschreibung
- name: personPreview
type: object[]
meta:
label: Personenvorschau
dependsOn:
eval: $parent.contentType == 'personPreview'
metaElements:
- initialImage
- hoverImage
subFields:
- name: initialImage
type: file
meta:
label: Bild
- name: hoverImage
type: file
meta:
label: Bild beim Hover
- name: name
type: string
meta:
label: Name
- name: link
type: string
meta:
label:
de: Seite
en: page
widget: select
choices:
endpoint: page
params:
sort: path
projection: navigation
mapping:
id: id
name: path
- name: boxList
type: object
meta:
label: Boxenliste
dependsOn:
eval: $parent.contentType == 'boxlist'
subFields:
- name: boxes
type: object[]
meta:
label: Boxen
subFields:
- name: name
type: string
meta:
label: Name
- name: extendableBoxes
type: object[]
meta:
label: Ausklappbare Box
dependsOn:
eval: $parent.contentType == 'extendableBoxes'
subFields:
- name: title
type: string
meta:
label: Titel
- name: text
type: string
meta:
widget: richtext
label: Text
- name: emailButton
type: boolean
meta:
label: E-Mail Button Anzeigen
- name: emailSubject
type: string
meta:
label: E-Mail default Betreff
dependsOn:
eval: $parent.emailButton == true
- name: textLink
type: object
meta:
label: Text Link
widget: containerLessObject
dependsOn:
eval: $parent.contentType == 'textLink'
subFields:

View File

@ -2,6 +2,7 @@
type: object[]
meta:
label: Boxen
widget: containerLessObjectArray
subFields: !include box.yml
- name: innerText

View File

@ -2,4 +2,5 @@
type: object[]
meta:
label: Boxen
widget: containerLessObjectArray
subFields: !include box.yml

View File

@ -0,0 +1,118 @@
- name: topTitle
type: string
meta:
label: Oberer Titel
helperText: "Dieser Titel wird in der Zeile oben angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-12"
large: "col-6"
- name: topTitleUpperCase
type: boolean
meta:
label: Oberer Titel in Großbuchstaben
helperText: "Ist dies aktiviert, so wird der obere Titel in Großbuchstaben angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-6"
large: "col-6"
- name: title
type: string
meta:
label: Titel
helperText: "Dieser Titel wird in der Zeile angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-6"
large: "col-6"
- name: subTitle
type: string
meta:
label: Untertitel
helperText: "Dieser Untertitel wird in der Zeile angezeigt."
containerProps:
layout:
size:
default: "col-6"
small: "col-6"
large: "col-6"
- name: backgroundImage
type: string
meta:
label: Hintergrundbild
helperText: "Dieses Bild wird als Hintergrundbild der Zeile angezeigt."
widget: foreignKey # Verwendetes Widget.
foreign:
collection: medialib # Name der Sammlung, in der die ausgewählten Daten gespeichert sind.
id: id # Feldname, das als eindeutige Kennung für die ausgewählten Daten verwendet wird.
subNavigation: 0 # Bestimmt, welche Navigation für die Auswahl der ausgewählten Daten angezeigt wird.
#projection: xyz
#sort: "title"
render:
defaultCollectionViews: true
- name: noBottomMargin
type: boolean
meta:
label: Kein unterer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand unter der Zeile angezeigt."
containerProps:
layout:
size:
default: "col-4"
small: "col-6"
large: "col-4"
- name: noTopMargin
type: boolean
meta:
label: Kein oberer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand über der Zeile angezeigt."
containerProps:
layout:
size:
default: "col-4"
small: "col-6"
large: "col-4"
- name: flexWrapNormal
type: boolean
meta:
label: Zeile normal umbrechen
helperText: "Ist dies aktiviert, so wird die Zeile normal und nicht reverse umgebrochen."
containerProps:
layout:
size:
default: "col-4"
small: "col-6"
large: "col-4"
- name: twoToThree
type: boolean
meta:
label: Zwei zu drei
helperText: "Ist dies aktiviert, so wird die Zeile in zwei zu drei Spalten aufgeteilt."
containerProps:
layout:
size:
default: "col-4"
small: "col-6"
large: "col-4"
- name: columns
type: object[]
meta:
label: Spalten
direction: row
widget: grid
subFields: !include ../fieldLists/column.yml

View File

@ -1,90 +0,0 @@
name: row
type: object
meta:
label: Zeile
metaElements:
- topTitle
- topTitleRed
- title
- subTitle
- pageTitle
subFields:
- name: topTitle
type: string
meta:
label: Oberer Titel
helperText: "Dieser Titel wird in der Zeile oben angezeigt."
- name: topTitleUpperCase
type: boolean
meta:
label: Oberer Titel in Großbuchstaben
helperText: "Ist dies aktiviert, so wird der obere Titel in Großbuchstaben angezeigt."
- name: title
type: string
meta:
label: Titel
helperText: "Dieser Titel wird in der Zeile angezeigt."
- name: subTitle
type: string
meta:
label: Untertitel
helperText: "Dieser Untertitel wird in der Zeile angezeigt."
- name: pageTitle
type: string
meta:
label: Titel der Seite
helperText: "Dieser Titel wird in der Seite als h1 angezeigt."
- name: backgroundImage
type: file
meta:
label: Hintergrundbild
helperText: "Dieses Bild wird als Hintergrundbild der Zeile angezeigt."
- name: noBottomMargin
type: boolean
meta:
label: Kein unterer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand unter der Zeile angezeigt."
- name: noTopMargin
type: boolean
meta:
label: Kein oberer Abstand
helperText: "Ist dies aktiviert, so wird kein Abstand über der Zeile angezeigt."
- name: flexWrapNormal
type: boolean
meta:
label: Zeile normal umbrechen
helperText: "Ist dies aktiviert, so wird die Zeile normal und nicht reverse umgebrochen."
- name: twoToThree
type: boolean
meta:
label: Zwei zu drei
helperText: "Ist dies aktiviert, so wird die Zeile in zwei zu drei Spalten aufgeteilt."
- name: nextPage
type: string
meta:
label: Nächste Seite
widget: select
choices:
endpoint: page
params:
sort: path
projection: navigation
mapping:
id: path
name: path
- name: columns
type: object[]
meta:
label: Spalten
direction: row
subFields: !include ../fieldLists/column.yml

View File

@ -0,0 +1,131 @@
# Der Name der Kollektion ist beliebig, aber wird in unserem
# Beispiel vom ContentBuilder als "medialib" referenziert.
name: medialib
uploadPath: ../media/medialib
meta:
label:
de: Medienbibliothek
en: Media Library
muiIcon: multimedia
defaultSort:
field: sort
order: MANUALLY
backup:
active: true
collectionName: backups
quickEdit:
enabled: true
fields:
- title
- description
- file
# "defaultImageFilter" dient auch hier nur zur Reduzierung der
# Bildgröße bei der Anzeige im tibi-admin (Listen).
# Die Bildgröße für die Einbindung ins erzeugte HTML des ContentBuilder
# hat hiermit nix zu tun.
defaultImageFilter: s
multiupload:
fields: []
views:
- type: table
mediaQuery: "(min-width: 0px)"
defaultSelect: false
selectionPriority: 2
fileDropArea:
label:
{
de: "Ziehen Sie Dateien per Drag and Drop hierher oder klicken Sie, um Dateien auszuwählen.",
en: "Drag and drop some files here, or click to upload.",
}
helperText: { de: "Maximale Uploadgröße: 1,54 MB", en: "Maximum upload size: 1.54MB" }
targetField: file
pageAsDropArea: false
columns:
- source: file
name: Datei
- source: updateTime
type: datetime
label: letztes Update
- type: cardList
mediaQuery: "(min-width: 1200px)"
selectionPriority: 1
fileDropArea:
label:
{
de: "Ziehen Sie Dateien per Drag and Drop hierher oder klicken Sie, um Dateien auszuwählen.",
en: "Drag and drop some files here, or click to upload.",
}
helperText: { de: "Maximale Uploadgröße: 1,54 MB", en: "Maximum upload size: 1.54MB" }
targetField: file
pageAsDropArea: false
fields:
- source: file
name: Datei
- source: updateTime
type: datetime
label: letztes Update
subNavigation:
- name: modalForeign # Name des Eingabefelds oder der Ansicht.
defaultSort: # Standard-Sortierkriterien, die angewendet werden, wenn keine anderen Sortierkriterien spezifiziert sind.
field: "path" # Standardmäßig wird nach dem "path"-Feld sortiert.
order: "ASC" # Standardmäßig wird in aufsteigender Reihenfolge (ASC) sortiert.
views: # Liste der Ansichten, die in diesem Feld angezeigt werden können.
- type: table # Es wird eine Tabellenansicht verwendet.
mediaQuery: "(min-width: 0px)" # Die Tabellenansicht wird nur angezeigt, wenn die Bildschirmbreite mindestens 0px beträgt.
columns: # Liste der Spalten, die in der Tabelle angezeigt werden.
- source: file
defaultCallback: # Standard-Callback-Funktion, die ausgeführt wird, wenn keine andere spezifiziert ist.
eval: | # Der Code wird als JavaScript evaluiert.
//js
(entry) => {
parent.selectEntry(entry)
}
//!js
permissions:
public:
methods:
get: true
post: false
put: false
delete: false
user:
methods:
get: true
post: true
put: true
delete: true
projections:
dashboard:
select:
fields:
- name: file
type: file
meta:
label:
de: Datei
en: File
- name: sort
type: number
meta:
label:
de: Manuelle Sortierung
en: Manual Sorting
inputProps:
{ readonly: true, placeholder: { de: "Wert wird automatisch gesetzt", en: "Value is set automatically" } }
helperText:
de: Dieses Feld wird für die manuelle Sortierung benötigt. Sobald ein Eintrag per Drag&Drop verschoben wurde, wird die neue Position innerhalb der Liste eingetragen.
en: This field is required for manual sorting. As soon as an entry is moved using Drag&Drop, the new position is entered in the list.

160
api/collections/module.yml Normal file
View File

@ -0,0 +1,160 @@
name: module
meta:
label: Module
backup:
active: true
collectionName: backups
views:
- type: table
columns:
- source: type
name: Typ
subNavigation:
- name: modal
views:
- type: table
columns:
- source: type
defaultCallback: # Standard-Callback-Funktion, die ausgeführt wird, wenn keine andere spezifiziert ist.
eval: | # Der Code wird als JavaScript evaluiert.
//js
(entry) => { // Diese Funktion nimmt den Eintrag (entry) als Argument.
parent.selectEntry(entry) // Die Funktion selectEntry auf dem übergeordneten Objekt wird mit dem Eintrag als Argument aufgerufen.
}
//!js
permissions:
public:
methods:
get: true
post: false
put: false
delete: false
user:
methods:
get: true
post: true
put: true
delete: true
imageFilter:
xs:
- fit: true
height: 90
width: 90
resampling: lanczos
quality: 60
s:
- fit: true
height: 300
width: 300
resampling: lanczos
quality: 60
m:
- fit: true
height: 600
width: 600
resampling: lanczos
quality: 60
l:
- fit: true
height: 1240
width: 1240
resampling: lanczos
quality: 60
xl:
- fit: true
height: 2000
width: 2000
resampling: lanczos
quality: 60
fields:
- name: type
type: string
meta:
label: Modultyp
helperText: "Wählen Sie den Typ des Moduls aus."
widget: select
choices:
- name: Arbeitskreislauf
id: iconCycleCircle
- name: Icons im Rechteck
id: iconCycleSquare
- name: Weltkarte
id: worldCard
- name: Chef Team
id: chefTeam
- name: Mitarbeiter Team
id: employeeTeam
- name: Stellenanzeigen Verlinkungen
id: jobOfferLink
- name: Stellenanzeigen
id: jobOffer
- name: jobOfferPage
type: string
meta:
label: Stellenanzeigen
widget: select
dependsOn:
eval: $parent.type == 'jobOfferLink'
choices:
endpoint: page
params:
sort: path
projection: navigation
mapping:
id: path
name: path
- name: iconCycleCircle
type: object
meta:
label: Icons im Kreis
widget: containerLessObject
dependsOn:
eval: $parent.type == 'iconCycleCircle'
subFields: !include fieldLists/iconCycleCircle.yml
- name: iconCycleSquare
type: object
meta:
label: Icons im Rechteck
dependsOn:
eval: $parent.type == 'iconCycleSquare'
subFields: !include fieldLists/iconCycleSquare.yml
- name: worldCard
type: object
meta:
label: Weltkarte
widget: containerLessObject
dependsOn:
eval: $parent.type == 'worldCard'
subFields:
- name: row
type: object[]
meta:
label: Weltkartenreihe
widget: grid
subFields:
- name: cards
type: object[]
meta:
label: Kartenspalten
widget: grid
direction: row
metaElements:
- verticalAlignment
- horizontalAlignment
subFields: !include fieldLists/cards.yml

View File

@ -13,6 +13,7 @@ meta:
mediaQuery: "(min-width:600px)"
columns:
- source: tree
name: Navigationsbaum
permissions:
public:
@ -28,8 +29,6 @@ permissions:
put: true
delete: false
fields:
- name: tree
type: number
@ -56,6 +55,8 @@ fields:
folding:
previewUnfolded: name
previewFolded: name
widget: containerLessObjectArray
subFields:
- name: name
type: string

View File

@ -27,6 +27,8 @@ meta:
collections:
- !include collections/navigation.yml
- !include collections/content.yml
- !include collections/module.yml
- !include collections/medialib.yml
- !include collections/backups.yml
assets:

View File

@ -4,13 +4,25 @@
import Menu from "./lib/components/Menu/Menu.svelte"
import NotFound from "./lib/components/NotFound.svelte"
import Rows from "./lib/components/Pagebuilder/Rows.svelte"
import { location, navigation, pages, serviceNavigation, rerender } from "./lib/store"
import {
location,
navigation,
pages,
serviceNavigation,
rerender,
mediaLibrary,
team,
jobOffers,
modules,
} from "./lib/store"
import { onMount, onDestroy } from "svelte"
import { Route, Router } from "svelte-routing"
import { loadPages } from "./lib/functions/getPages"
import { loadNavigation } from "./lib/functions/loadNavigation"
import ScrollTop from "./lib/components/widgets/scrollTop.svelte"
import ScrollDown from "./lib/components/widgets/scrollDown.svelte"
import { loadLibrary } from "./lib/functions/loadLibrary"
import { loadModules } from "./lib/functions/loadModules"
export let url = ""
if (url) {
@ -28,11 +40,24 @@
async function getPages() {
let pagesArray = await loadPages()
let pagesRes: Pages = {}
let teamRes: Pages = {}
let jobOffersRes: Pages = {}
pagesArray.forEach((e) => {
pagesRes[e.path] = e
if (!e.active) return
if (e.type == "page") {
pagesRes[e.path] = e
} else if (e.type == "teamMembers") {
teamRes[e.path] = e
} else if (e.type == "jobOffers") {
jobOffersRes[e.path] = e
} else {
pagesRes[e.path] = e
}
})
$pages = pagesRes
$team = teamRes
$jobOffers = jobOffersRes
}
async function getNavigation() {
@ -41,8 +66,28 @@
$serviceNavigation = nav[1]
}
async function getLibrary() {
let library: MediaLibrary[] = await loadLibrary()
let lib = {}
library.forEach((e) => {
lib[e.id] = e
})
$mediaLibrary = lib
}
async function getModules() {
let moduleArray: Module[] = await loadModules()
let mod = {}
moduleArray.forEach((e) => {
mod[e.id] = e
})
$modules = mod
}
getNavigation()
getPages()
getLibrary()
getModules()
let activeMenu = false
$: {

View File

@ -4,9 +4,10 @@
let nextpage = $navigation?.pages[0]
$: nextpage = $navigation?.pages[0]
function getNextPage(pages) {
console.log(pages, "pages")
if (location.pathname == "/" || location.pathname == "") return
if (location.pathname == "/" || location.pathname == "") {
$navigation?.pages?.length > 1 ? (nextpage = $navigation?.pages[1]) : (nextpage = $navigation?.pages[0])
return
}
let currPage = pages.find(
(page) => Object.values($pages)?.find((o) => o.id == page.page)?.path == location.pathname
)

View File

@ -5,6 +5,8 @@
import TextLink from "../widgets/textLink.svelte"
let teasers = Object.values($pages)?.map((page) => ({ teaser: page.teaser, path: page.path }))
$: teasers = Object.values($pages)?.map((page) => ({ teaser: page.teaser, path: page.path }))
console.log("teasers:", teasers)
register(false)
let swiper

View File

@ -0,0 +1,32 @@
<script lang="ts">
import { jobOffers, modules, team } from "../../store"
import Worldcard from "../widgets/Worldcard/worldcard.svelte"
import Boxlist from "../widgets/boxlist.svelte"
import ExtendableBox from "../widgets/extendableBox.svelte"
import IconCycleBox from "../widgets/iconCycleBox.svelte"
import IconCycleCircle from "../widgets/iconCycleCircle.svelte"
import PageLinkBlocks from "../widgets/pageLinkBlocks.svelte"
import Persons from "../widgets/persons.svelte"
export let col: { contentType: "moduleImport"; moduleImport: string }
export let pageId: string
let module = $modules[col.moduleImport] || {}
$: module = $modules[col.moduleImport] || {}
</script>
{#if module.type == "iconCycleCircle"}
<IconCycleCircle iconCycleCircle="{module.iconCycleCircle}" pageId="{pageId}" />
{:else if module.type == "iconCycleSquare"}
<IconCycleBox iconCycleSquare="{module.iconCycleSquare}" pageId="{pageId}" />
{:else if module.type == "worldCard"}
<Worldcard worldCard="{module.worldCard}" pageId="{pageId}" />
{:else if module.type == "chefTeam"}
<Persons persons="{Object.values($team).filter((p) => p.personType == 'chef')}" pageId="{pageId}" />
{:else if module.type == "employeeTeam"}
<Boxlist persons="{Object.values($team).filter((p) => p.personType == 'employee')}" />
{:else if module.type == "jobOffer"}
<ExtendableBox pages="{Object.values($jobOffers)}" />
{:else if module.type == "jobOfferLink"}
<PageLinkBlocks pages="{Object.values($jobOffers)}" pageReference="{module.jobOfferPage}" />
{/if}

View File

@ -14,26 +14,19 @@
import TextLink from "../widgets/textLink.svelte"
import TopDown from "../widgets/topDown.svelte"
import WorldCard from "../widgets/Worldcard/worldcard.svelte"
import { pages, rerender } from "../../store"
import { modules, pages, rerender, team } from "../../store"
import IconCycleCircle from "../widgets/iconCycleCircle.svelte"
import IconCycleBox from "../widgets/iconCycleBox.svelte"
import Module from "./Module.svelte"
export let row: Row
export let pageId: string
export let bright: boolean
export let isHP: boolean
function checkNestedPath() {
const pathSegments = location.pathname.split("/").filter((segment) => segment.length)
if (pathSegments.length > 1) {
pathSegments.pop() // remove the last segment
return "/" + pathSegments.join("/")
}
return ""
}
let nestedPath = checkNestedPath()
export let i: number
export let page: Page
export let personPage: boolean
console.log("page", page, personPage)
window.addEventListener("popstate", function (event) {
$rerender = $rerender + 1
})
@ -41,18 +34,19 @@
{#if Object.keys(row).length}
{#if row.topTitle}
<h3 class="{row.topTitleUpperCase ? 'hph3' : 'nmh3'}" class:red="{row.topTitleRed}">
<h3 class="{row.topTitleUpperCase ? 'hph3' : 'nmh3'}">
{row.topTitle}
</h3>
{/if}
{#if nestedPath}
{#if personPage}
<div class="top-header" style="display: flex; width: 100%; justify-content: space-between;">
<h3
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown
on:click="{() => {
navigate('/' + location.pathname.split('/').at(1))
$rerender = $rerender + 1
navigate(nestedPath)
}}"
>
<img src="/media/arrow-l.svg" alt="arrow" /> Zurück zur Übersicht
@ -61,16 +55,21 @@
style="cursor: pointer; display: flex; align-items: center; gap: 10px; line-height: 1.4;"
on:keydown
on:click="{() => {
let chefs = Object.values($team).filter((p) => p.personType == 'chef')
let i = chefs.findIndex((p) => p.path == page.path)
if (i == chefs.length - 1) i = 0
else i++
navigate(chefs[i].path)
$rerender = $rerender + 1
navigate(row?.nextPage || nestedPath)
}}"
>
Zum nächsten Profil <img src="/media/arrowr.svg" alt="arrow" />
</h3>
</div>
{/if}
{#if row.pageTitle}
<h1>{row.pageTitle}</h1>
{#if page.pageTitle && i == 0}
<h1>{page.pageTitle}</h1>
{/if}
{#if row.title}
<h2 class="">{row.title}</h2>
@ -83,10 +82,16 @@
class="row"
class:twoToThree="{row.twoToThree}"
class:normalWrap="{row.flexWrapNormal}"
class:dominant="{row.columns.some((col) => col.contentType == 'iconCycleCircle')}"
class:dominant="{row.columns.some(
(col) => col.contentType == 'moduleImport' && $modules?.[col.moduleImport]?.type == 'iconCycleCircle'
)}"
>
{#each row?.columns as col}
<div class="col" class:dominant="{col.contentType == 'iconCycleCircle'}">
<div
class="col"
class:dominant="{col.contentType == 'moduleImport' &&
$modules?.[col.moduleImport]?.type == 'iconCycleCircle'}"
>
{#if col?.contentType == "text"}
<Text text="{col?.text}" />
{:else if col?.contentType == "textLink"}
@ -95,12 +100,12 @@
path="{Object.values($pages)?.find((o) => o.id == col.textLink.link)?.path || '/'}"
bright="{bright}"
/>
{:else if col.contentType == "moduleImport"}
<Module col="{col}" pageId="{pageId}" />
{:else if col.contentType == "image"}
<Image image="{col?.image}" col="{col}" pageId="{pageId}" />
{:else if col.contentType == "iconBlocks"}
<IconBlock pageId="{pageId}" col="{col}" />
{:else if col.contentType == "pageLinkBlocks"}
<PageLinkBlocks col="{col}" />
{:else if col.contentType == "networkEvents"}
<Events col="{col}" pageId="{pageId}" />
{:else if col.contentType == "publications"}
@ -111,18 +116,6 @@
<InfoBoard col="{col}" pageId="{pageId}" />
{:else if col.contentType == "nestedCard"}
<NestedCard col="{col}" />
{:else if col.contentType == "boxlist"}
<Boxlist col="{col}" />
{:else if col.contentType == "extendableBoxes"}
<ExtendableBox col="{col}" />
{:else if col.contentType == "personPreview"}
<Persons col="{col}" pageId="{pageId}" />
{:else if col.contentType == "iconCycleCircle"}
<IconCycleCircle col="{col}" pageId="{pageId}" />
{:else if col.contentType == "iconCycleSquare"}
<IconCycleBox col="{col}" pageId="{pageId}" />
{:else if col.contentType == "worldCard"}
<WorldCard col="{col}" pageId="{pageId}" />
{/if}
</div>
{/each}

View File

@ -1,27 +1,35 @@
<script lang="ts">
import { pages, scrollToRowNr } from "../../store"
import { mediaLibrary, pages, scrollToRowNr, team } from "../../store"
import Homepage from "./Homepage.svelte"
import Pagebuilder from "./Pagebuilder.svelte"
import { apiBaseURL } from "../../../config"
import { onMount } from "svelte"
export let path
export let path: string
export let homepage = false
export let image: FileField
let page: Page
let personPage = false
function initPage() {
page = $pages[path]
if ($pages[path]) {
page = $pages[path]
} else if (
Object.values($team)
.map((p) => p.path == path)
.includes(true)
) {
page = Object.values($team).find((p) => p.path == path)
personPage = true
}
}
onMount(() => {
if ($scrollToRowNr !== -1) {
console.log("test321-", $scrollToRowNr)
if (!$scrollToRowNr) {
$scrollToRowNr = -1
return
}
let element = document.getElementById("row-" + $scrollToRowNr)
console.log(element)
if (!element) {
$scrollToRowNr = -1
return
@ -35,7 +43,7 @@
})
$: {
if (Object.keys($pages).length) {
if (Object.keys($pages).length || Object.keys($team).length) {
initPage()
}
}
@ -50,22 +58,29 @@
id="row-{i}"
style="{path == '/' && i == page.rows.length - 1
? 'padding-bottom: 300px; margin-bottom: -40px;'
: ''} {row.row.noBottomMargin ? 'margin-bottom: 0px; padding-bottom: 0px;' : ''} {row.row
.noTopMargin
: ''} {row.noBottomMargin ? 'margin-bottom: 0px; padding-bottom: 0px;' : ''} {row.noTopMargin
? 'margin-top: 0px; padding-top: 0px;'
: ''}"
>
{#if row.row.backgroundImage}
{#if row.backgroundImage && mediaLibrary[row.backgroundImage]}
<div class="background-image">
<img src="{`${apiBaseURL}page/${page.id}/${row.row.backgroundImage?.src}`}" alt="img" />
<img
src="{`${apiBaseURL}medialib/${row?.backgroundImage}/${
mediaLibrary?.[row?.backgroundImage]?.file?.src
}`}"
alt="img"
/>
</div>
{/if}
<div class="content" class:bright="{row.row.backgroundImage}">
<div class="content" class:bright="{row.backgroundImage}">
<Pagebuilder
personPage="{personPage}"
isHP="{path == '/'}"
row="{row.row}"
i="{i}"
row="{row}"
page="{page}"
pageId="{page.id}"
bright="{!!row.row.backgroundImage}"
bright="{!!row.backgroundImage}"
/>
</div>
</div>

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { apiBaseURL } from "../../../../config"
import { mediaLibrary } from "../../../store"
export let card: Card
export let properties: string[][]
@ -23,7 +24,7 @@
</script>
<div class="card">
<img src="{apiBaseURL}page/{pageId}/{card.image.src}" alt="card" />
<img src="{apiBaseURL}medialib/{card.image}/{$mediaLibrary?.[card?.image]?.file?.src}" alt="card" />
<div class="content">
<div

View File

@ -2,7 +2,7 @@
import Card from "./card.svelte"
import Selectbox from "./selectbox.svelte"
export let col: Column
export let worldCard: WorldCard
export let pageId: string
let availableProperties = [
@ -38,9 +38,9 @@
<div style="display: flex; flex-direction: column; width: 100%; align-items: center;">
<div class="worldcard">
<div class="worldcard">
{#each col.worldCard.row as row}
{#each worldCard?.row as row}
<div class="wc-row">
{#each row.cards as card}
{#each row?.cards as card}
<Card
card="{card}"
properties="{availableProperties}"

View File

@ -1,20 +1,18 @@
<script lang="ts">
export let col: Column
// A function to compare first names and sort the array
export let persons: Page[]
let boxes = persons.map((p) => p.personPreview.name)
const sortByFirstName = (a, b) => {
const nameA = a.name.split(" ")[0] // Extracts the first name from "First Last"
const nameB = b.name.split(" ")[0]
return nameA.localeCompare(nameB)
}
col.boxList.boxes.sort(sortByFirstName) // Sorts the array in place
boxes = boxes.sort(sortByFirstName)
</script>
<div class="boxList">
{#each col.boxList.boxes as name}
{#each boxes as name}
<div class="box">
{name.name}
{name}
</div>
{/each}
</div>

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { mediaLibrary } from "../../store"
export let col: Column
export let pageId: string
@ -44,7 +45,11 @@
</div>
<div class="details">
<em>{nE.title}</em>
<a href="{apiBaseURL}page/{pageId}/{nE.file.src}" style="text-decoration: none;" download="{apiBaseURL}page/{pageId}/{nE.file.src}">
<a
href="{apiBaseURL}medialib/{nE.file}/{$mediaLibrary?.[nE?.file]?.file?.src}"
style="text-decoration: none;"
download="{apiBaseURL}medialib/{nE.file}/{$mediaLibrary?.[nE?.file]?.file?.src}"
>
<button class="more">mehr</button></a
>
</div>

View File

@ -2,39 +2,36 @@
import { onMount } from "svelte"
import { openExtendableNr } from "../../store"
export let col: Column
export let opened = -1
export let pages: Page[]
export let opened = ""
let jobOffers = pages.map((p) => p.jobOffer)
onMount(() => {
if (!isNaN($openExtendableNr) && $openExtendableNr !== -1) {
opened = $openExtendableNr
$openExtendableNr = -1
}
opened = location.search.split("=").at(-1)
})
</script>
<div class="boxes">
{#each col.extendableBoxes as box, i}
<div class="box" class:opened="{i == opened}">
{#each jobOffers as box, i}
<div class="box" class:opened="{pages[i].id == opened}">
<div
class="upper"
on:keydown
on:click="{() => {
if (opened == i) opened = -1
else opened = i
if (opened == pages[i].id) opened = ''
else opened = pages[i].id
}}"
>
<h4>
{box.title}
</h4>
<div>
{#if i !== opened}<img src="/media/down.svg" alt="arrow" />{:else}<img
{#if pages[i].id !== opened}<img src="/media/down.svg" alt="arrow" />{:else}<img
src="/media/up.svg"
alt="arrow"
/>{/if}
</div>
</div>
<div class="content" class:closed="{i !== opened}">
<div class="content" class:closed="{pages[i].id !== opened}">
{@html box.text}
{#if box.emailButton}
<a

View File

@ -1,15 +1,15 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { mediaLibrary } from "../../store"
export let pageId: string
export let col: Column
</script>
<div class="iconBlock">
{#each col.iconBlocks as icon}
<div class="icon">
<img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
<img src="{`${apiBaseURL}medialib/${icon.icon}/${mediaLibrary?.[icon?.icon]?.file?.src}`}" alt="img" />
<div class="text">
<em>{icon.bigText}</em>
<p>{icon.smallText}</p>

View File

@ -1,24 +1,25 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
export let col: Column
import { mediaLibrary } from "../../store"
export let iconCycleSquare: IconCycleSquare
export let pageId: string
console.log("YEY")
let active = -1
setInterval(() => {
active += 1
if (active == col.iconCycleSquare.boxes.length) active = 0
if (active == iconCycleSquare.boxes.length) active = 0
}, 1250)
</script>
<div class="iconCycleSquares">
{#each col?.iconCycleSquare?.boxes as box, i}
{#each iconCycleSquare?.boxes as box, i}
<div class="box" id="box{i}" class:active="{i == active}">
<div class="content">
<div class="icon">
<svg
stroke="{i == active ? 'black' : 'white'}"
fill="{i == active ? 'black' : 'white'}"
data-src="{apiBaseURL}page/{pageId}/{box.icon?.src}"></svg>
data-src="{apiBaseURL}medialib/{box?.icon}/{$mediaLibrary?.[box?.icon]?.file?.src}"></svg>
</div>
<div class="text">
{box.text}

View File

@ -1,11 +1,13 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { onMount } from "svelte"
import { mediaLibrary } from "../../store"
export let iconCycleCircle: IconCycleCircle
export let col: Column
export let pageId: string
let count = col.iconCycleCircle.boxes.length // The number of surrounding circles.
let count = iconCycleCircle.boxes.length // The number of surrounding circles.
let angleStep = 360 / count
let radius = 310
@ -34,7 +36,7 @@
<div class="container">
<div class="main-circle">
<div class="content">
{col.iconCycleCircle.innerText}
{iconCycleCircle.innerText}
</div>
{#each circles as { x, y, rotation }, i}
<div
@ -52,10 +54,12 @@
id="mySvgObject{i}"
stroke="{i == focused ? 'white' : 'black'}"
fill="{i == focused ? 'white' : 'black'}"
data-src="{apiBaseURL}page/{pageId}/{col.iconCycleCircle?.boxes[i]?.icon?.src}"></svg>
data-src="{apiBaseURL}medialib/{iconCycleCircle?.boxes[i]?.icon}/{$mediaLibrary[
iconCycleCircle?.boxes[i]?.icon
]?.file?.src}"></svg>
</div>
<div class="text" style="text-align: center;">
{@html col.iconCycleCircle?.boxes[i]?.text}
{@html iconCycleCircle?.boxes[i]?.text}
</div>
</div>
</div>

View File

@ -1,19 +1,23 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
export let image: FileField
import { mediaLibrary } from "../../store"
export let image: string
export let pageId: string
export let col: Column
export let col: { contentType: "image"; image: string; icons: { icon: string; link: string }[] }
</script>
<div class="image-container">
<img src="{`${apiBaseURL}page/${pageId}/${image?.src}`}" alt="img" />
<img src="{`${apiBaseURL}medialib/${image}/${$mediaLibrary[image]?.file?.src}`}" alt="img" />
</div>
{#if col && col.icons}
<div class="icons">
{#each col.icons as icon}
<div class="icon">
<a href="{icon.link}" style="text-decoration: none;" target="_blank">
<img src="{`${apiBaseURL}page/${pageId}/${icon.icon?.src}`}" alt="img" />
<img
src="{`${apiBaseURL}medialib/${icon.icon}/${$mediaLibrary[icon.icon]?.file?.src}`}"
alt="img"
/>
</a>
</div>
{/each}

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { mediaLibrary } from "../../store"
export let col: Column
export let pageId: string
@ -8,7 +9,10 @@
<div class="infoBoard">
<div class="header">
<div class="icon">
<img src="{`${apiBaseURL}page/${pageId}/${col.infoBoard.icon?.src}`}" alt="img" />
<img
src="{`${apiBaseURL}medialib/${col.infoBoard.icon}/${$mediaLibrary[col.infoBoard.icon]?.file?.src}`}"
alt="img"
/>
</div>
<div class="title">
{col.infoBoard.title}

View File

@ -1,22 +1,23 @@
<script lang="ts">
import { navigate } from "svelte-routing/src/history"
import { openExtendableNr, pages, rerender, scrollToRowNr } from "../../store"
export let col: Column
import { openExtendableNr, rerender, scrollToRowNr } from "../../store"
export let pages: Page[]
export let pageReference: string
let jobOffers = pages.map((p) => p.jobOffer)
let focused = -1
</script>
<div class="link-container">
{#each col.pageLinkBlocks as link, i}
{#if isNaN(link.extendableRowNr)}
{#each jobOffers as job, i}
{#if i < 3}
<button
class="page-ref"
on:click="{() => {
$rerender = $rerender + 1
$scrollToRowNr = link.rowNr
navigate(Object.values($pages)?.find((o) => o.id == link.page)?.path || '/')
navigate(pageReference + '?elem=' + pages[i].id)
}}"
>
{link.name}
{job.title}
</button>
{:else}
<button
@ -29,14 +30,10 @@
class="row-ref fill"
on:click="{() => {
$rerender = $rerender + 1
$scrollToRowNr = link.rowNr
$openExtendableNr = link.extendableRowNr
navigate(Object.values($pages)?.find((o) => o.id == link.page)?.path || '/')
navigate(pageReference)
}}"
>
<div>
{link.name}
</div>
<div>Mehr offene Stellen</div>
<svg
data-src="/media/arrow-r.svg"
stroke="{i == focused ? '#fff' : 'black'}"

View File

@ -1,39 +1,45 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { pages, rerender } from "../../store"
import { mediaLibrary, pages, rerender } from "../../store"
import { navigate } from "svelte-routing/src/history"
export let pageId: string
export let col: Column
export let persons: Page[]
let hover = -1
</script>
<div class="persons">
{#each col.personPreview as pp, i}
{#each persons as p, i}
<button
class="person"
on:click="{() => {
$rerender = $rerender + 1
navigate(Object.values($pages)?.find((o) => o.id == pp.link)?.path || '/')
navigate(p.path)
}}"
>
<div class="image" on:mouseover="{() => (hover = i)}" on:focus on:blur on:mouseout="{() => (hover = -1)}">
<!-- Initial Image -->
<img
class="initial"
src="{`${apiBaseURL}page/${pageId}/${pp.initialImage?.src}`}"
src="{`${apiBaseURL}medialib/${p.personPreview.initialImage}/${
$mediaLibrary[p.personPreview.initialImage]?.file?.src
}`}"
alt="img"
style="opacity: {hover == i ? 0 : 1}"
/>
<!-- Hover Image -->
<img
class="hover"
src="{`${apiBaseURL}page/${pageId}/${pp.hoverImage?.src}`}"
src="{`${apiBaseURL}medialib/${p.personPreview.hoverImage}/${
$mediaLibrary[p.personPreview.hoverImage]?.file?.src
}`}"
alt="img"
style="opacity: {hover == i ? 1 : 0}"
/>
</div>
<div class="text">
{pp.name}
{p.personPreview.name}
</div>
</button>
{/each}

View File

@ -1,5 +1,6 @@
<script lang="ts">
import { apiBaseURL } from "../../../config"
import { mediaLibrary } from "../../store"
export let col: Column
export let pageId: string
@ -20,8 +21,8 @@
<div class="content">{@html publication.content}</div>
<div class="download">
<a
href="{apiBaseURL}page/{pageId}/{publication.file.src}"
download="{apiBaseURL}page/{pageId}/{publication.file.src}"
href="{apiBaseURL}medialib/{publication.file}/{$mediaLibrary[publication.file]?.file.src}"
download="{apiBaseURL}medialib/{publication.file}/{$mediaLibrary[publication.file]?.file.src}"
>
<button class="download-button">zur Publikation</button>
</a>

View File

@ -0,0 +1,6 @@
import { api } from "../../api"
export async function loadLibrary(): Promise<MediaLibrary[]> {
let lib = await api<MediaLibrary[]>("medialib", {})
return lib.data
}

View File

@ -0,0 +1,6 @@
import { api } from "../../api"
export async function loadModules(): Promise<Module[]> {
let module = await api<Module[]>("module", {})
return module.data
}

View File

@ -12,6 +12,10 @@ export const location = writable(initLoc)
export let navigation = writable<Navigation>()
export let pages = writable<Pages>({})
export let team = writable<Pages>({})
export let jobOffers = writable<Pages>({})
export let modules = writable<{ [id: string]: Module }>({})
export let mediaLibrary = writable<{ [id: string]: MediaLibrary }>({})
export let serviceNavigation = writable<Navigation>()
export let rerender = writable(0)
export let scrollToRowNr = writable(-1)

116
types/global.d.ts vendored
View File

@ -10,9 +10,14 @@ interface Pages {
interface Page {
path: string
active: boolean
type: "page" | "teamMembers" | "jobOffers"
pageTitle: string
personType: string
personPreview: PersonPreview
teaser: teaserHomepage
sectionHomepage: Row
rows: outerRow[]
jobOffer: jobOffer
rows: Row[]
id: string
}
@ -22,62 +27,48 @@ interface teaserHomepage {
teaserTitle: string
teaserDescription: string
}
interface outerRow {
row: Row
}
interface Row {
topTitle: string
topTitleRed: boolean
subTitle: string
topTitleUpperCase: boolean
title: string
pageTitle: string
subTitle: string
backgroundImage: string
noBottomMargin: boolean
noTopMargin: boolean
flexWrapNormal: boolean
twoToThree: boolean
columns: Column[]
backgroundImage: FileField
}
interface Column {
contentType:
| "image"
| "iconCycleSquare"
| "iconCycleCircle"
| "text"
| "infoBoard"
| "worldCard"
| "nestedCard"
| "topDown"
| "personPreview"
| "boxlist"
| "extendableBoxes"
| "textLink"
| "iconBlocks"
| "pageLinkBlocks"
| "publications"
| "networkEvents"
type Column =
| { contentType: "image"; image: string; icons: { icon: string; link: string }[] }
| { contentType: "moduleImport"; moduleImport: string }
| { contentType: "text"; text: string }
| { contentType: "infoBoard"; infoBoard: InfoBoard }
| { contentType: "nestedCard"; nestedCard: NestedCard[] }
| { contentType: "topDown"; topDown: TopDown }
| { contentType: "textLink"; textLink: TextLink }
| { contentType: "iconBlocks"; iconBlocks: IconBlock[] }
| { contentType: "networkEvents"; networkEvents: NetworkEvent[] }
| { contentType: "publications"; publications: Publication[] }
image?: FileField
icons: {
icon: FileField
link: string
}[]
iconCycleSquare?: IconCycleSquare
iconCycleCircle?: IconCycleCircle
text: string
textLink: TextLink
infoBoard: InfoBoard
worldCard: WorldCard
nestedCard: NestedCard[]
topDown: TopDown
personPreview: PersonPreview[]
boxList: BoxList
extendableBoxes: ExtendableBox[]
iconBlocks: iconBlock[]
pageLinkBlocks: pageLinkBlock[]
networkEvents: NetworkEvent[]
publications: Publication[]
interface MediaLibrary {
file: FileField
id: string
}
type Module =
| { id: string; type: "iconCycleCircle"; iconCycleCircle: IconCycleCircle }
| { id: string; type: "iconCycleSquare"; iconCycleSquare: IconCycleSquare }
| { id: string; type: "worldCard"; worldCard: WorldCard }
| { id: string; type: "chefTeam" }
| { id: string; type: "employeeTeam" }
| { id: string; type: "jobOfferLink"; jobOfferPage: string }
| { id: string; type: "jobOffer" }
interface Publication {
file: FileField
file: string
content: string
}
@ -85,23 +76,15 @@ interface NetworkEvent {
beginDate: Date
endDate: Date
title: string
file: FileField
file: string
}
interface iconBlock {
icon: FileField
iconFocused: FileField
icon: string
bigText: string
smallText: string
}
interface pageLinkBlock {
name: string
rowNr: number
page: string
extendableRowNr: number
}
interface IconCycleSquare {
boxes: Box[]
}
@ -112,19 +95,19 @@ interface IconCycleCircle {
}
interface Box {
icon: FileField
icon: string
text: string
circle: boolean
}
interface InfoBoard {
title: string
icon: FileField
icon: string
text: string
}
interface WorldCard {
rows: WorldCardRow[]
row: WorldCardRow[]
}
interface worldCardRow {
cards: Card[]
@ -133,7 +116,7 @@ interface worldCardRow {
interface Card {
verticalAlignment: string
horizontalAlignment: string
image: FileField
image: string
title: string
properties: number[]
}
@ -154,10 +137,9 @@ interface TopDownRow {
}
interface PersonPreview {
initialImage: FileField
hoverImage: FileField
initialImage: string
hoverImage: string
name: string
link: string
}
interface BoxList {
@ -166,14 +148,14 @@ interface BoxList {
}[]
}
interface ExtendableBox {
interface jobOffer {
title: string
text: string
emailButton: boolean
emailSubject: string
}
interface FileField {
interface string {
path: string
src: string
type: string