System generated commit, initial commit
This commit is contained in:
@@ -0,0 +1,897 @@
|
||||
export default {
|
||||
ALL_VALUE: "__ALL__",
|
||||
|
||||
CORE_COLUMNS: [
|
||||
"Vorgang",
|
||||
"Name",
|
||||
"Vorname",
|
||||
"E-Mail",
|
||||
"Email",
|
||||
"Geb.-Datum",
|
||||
"Zus_Wunsch",
|
||||
"Skipassnummer"
|
||||
],
|
||||
|
||||
getWorkbook() {
|
||||
const file = Dateiupload.files?.[0];
|
||||
|
||||
if (!file) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const rawData = file.data;
|
||||
|
||||
if (
|
||||
rawData === null ||
|
||||
rawData === undefined ||
|
||||
rawData === ""
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (typeof rawData === "string") {
|
||||
try {
|
||||
return JSON.parse(rawData);
|
||||
} catch (error) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
return rawData;
|
||||
},
|
||||
|
||||
getSheetRows() {
|
||||
const workbook = this.getWorkbook();
|
||||
|
||||
if (
|
||||
!Array.isArray(workbook) ||
|
||||
workbook.length === 0
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/*
|
||||
* Appsmith liefert Excel-Dateien meist so:
|
||||
*
|
||||
* [
|
||||
* {
|
||||
* name: "!Leistungsliste",
|
||||
* data: [
|
||||
* ["Vorgang", "Name", "Vorname"],
|
||||
* ["98555", "Statz", "Hannah"]
|
||||
* ]
|
||||
* }
|
||||
* ]
|
||||
*/
|
||||
if (
|
||||
workbook[0] !== null &&
|
||||
typeof workbook[0] === "object" &&
|
||||
!Array.isArray(workbook[0]) &&
|
||||
Array.isArray(workbook[0].data)
|
||||
) {
|
||||
const preferredSheet =
|
||||
workbook.find(sheet =>
|
||||
String(sheet?.name ?? "")
|
||||
.toLowerCase()
|
||||
.includes("leistungsliste")
|
||||
);
|
||||
|
||||
const selectedSheet =
|
||||
preferredSheet ?? workbook[0];
|
||||
|
||||
return Array.isArray(selectedSheet?.data)
|
||||
? selectedSheet.data
|
||||
: [];
|
||||
}
|
||||
|
||||
/*
|
||||
* Alternativ können die Zeilen direkt geliefert werden.
|
||||
*/
|
||||
return workbook;
|
||||
},
|
||||
|
||||
createUniqueHeaders(headerRow) {
|
||||
const usedHeaders = {};
|
||||
|
||||
return headerRow.map((value, index) => {
|
||||
let header = String(value ?? "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
|
||||
if (!header) {
|
||||
header = `Spalte_${index + 1}`;
|
||||
}
|
||||
|
||||
usedHeaders[header] =
|
||||
(usedHeaders[header] ?? 0) + 1;
|
||||
|
||||
if (usedHeaders[header] > 1) {
|
||||
return `${header}_${usedHeaders[header]}`;
|
||||
}
|
||||
|
||||
return header;
|
||||
});
|
||||
},
|
||||
|
||||
rowsAsObjects() {
|
||||
const rows = this.getSheetRows();
|
||||
|
||||
if (
|
||||
!Array.isArray(rows) ||
|
||||
rows.length === 0
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/*
|
||||
* Daten liegen bereits als Objekte vor.
|
||||
*/
|
||||
if (
|
||||
rows[0] !== null &&
|
||||
typeof rows[0] === "object" &&
|
||||
!Array.isArray(rows[0])
|
||||
) {
|
||||
return rows.filter(row =>
|
||||
Object.values(row).some(value =>
|
||||
String(value ?? "").trim() !== ""
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Daten liegen als Zeilen-Arrays vor.
|
||||
* Erste Zeile wird als Überschrift verwendet.
|
||||
*/
|
||||
if (!Array.isArray(rows[0])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const headers =
|
||||
this.createUniqueHeaders(rows[0]);
|
||||
|
||||
return rows
|
||||
.slice(1)
|
||||
.filter(row =>
|
||||
Array.isArray(row) &&
|
||||
row.some(value =>
|
||||
String(value ?? "").trim() !== ""
|
||||
)
|
||||
)
|
||||
.map(row => {
|
||||
const result = {};
|
||||
|
||||
headers.forEach((header, index) => {
|
||||
result[header] = row[index] ?? "";
|
||||
});
|
||||
|
||||
return result;
|
||||
});
|
||||
},
|
||||
|
||||
cleanText(value) {
|
||||
return String(value ?? "").trim();
|
||||
},
|
||||
|
||||
isBooked(value) {
|
||||
const normalized = String(value ?? "")
|
||||
.trim()
|
||||
.toLowerCase();
|
||||
|
||||
const emptyValues = [
|
||||
"",
|
||||
"0",
|
||||
"false",
|
||||
"nein",
|
||||
"no",
|
||||
"n",
|
||||
"null",
|
||||
"undefined",
|
||||
"-"
|
||||
];
|
||||
|
||||
return !emptyValues.includes(normalized);
|
||||
},
|
||||
|
||||
formatExcelDate(value) {
|
||||
if (
|
||||
value === null ||
|
||||
value === undefined ||
|
||||
value === ""
|
||||
) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const numericValue = Number(value);
|
||||
|
||||
/*
|
||||
* Excel-Datumswerte sind fortlaufende Nummern.
|
||||
* Beispiel: 41495 wird zu einem echten Datum.
|
||||
*/
|
||||
if (
|
||||
Number.isFinite(numericValue) &&
|
||||
numericValue > 20000 &&
|
||||
numericValue < 100000
|
||||
) {
|
||||
const milliseconds =
|
||||
Math.round(
|
||||
(numericValue - 25569) *
|
||||
86400 *
|
||||
1000
|
||||
);
|
||||
|
||||
const date = new Date(milliseconds);
|
||||
|
||||
if (!Number.isNaN(date.getTime())) {
|
||||
const day = String(
|
||||
date.getUTCDate()
|
||||
).padStart(2, "0");
|
||||
|
||||
const month = String(
|
||||
date.getUTCMonth() + 1
|
||||
).padStart(2, "0");
|
||||
|
||||
const year =
|
||||
date.getUTCFullYear();
|
||||
|
||||
return `${day}.${month}.${year}`;
|
||||
}
|
||||
}
|
||||
|
||||
return this.cleanText(value);
|
||||
},
|
||||
|
||||
getServiceColumns() {
|
||||
const rows = this.rowsAsObjects();
|
||||
|
||||
if (rows.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object.keys(rows[0])
|
||||
.filter(column =>
|
||||
!this.CORE_COLUMNS.includes(column)
|
||||
)
|
||||
.filter(column =>
|
||||
!column.startsWith("Spalte_")
|
||||
);
|
||||
},
|
||||
|
||||
getSavedState() {
|
||||
const state =
|
||||
appsmith.store?.checkinState;
|
||||
|
||||
if (
|
||||
state !== null &&
|
||||
typeof state === "object" &&
|
||||
!Array.isArray(state)
|
||||
) {
|
||||
return state;
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
|
||||
createPersonId(rawRow, index) {
|
||||
const vorgang =
|
||||
this.cleanText(rawRow["Vorgang"]);
|
||||
|
||||
const name =
|
||||
this.cleanText(rawRow["Name"]);
|
||||
|
||||
const vorname =
|
||||
this.cleanText(rawRow["Vorname"]);
|
||||
|
||||
const email =
|
||||
this.cleanText(
|
||||
rawRow["E-Mail"] ??
|
||||
rawRow["Email"]
|
||||
);
|
||||
|
||||
const gebDatum =
|
||||
this.cleanText(rawRow["Geb.-Datum"]);
|
||||
|
||||
return [
|
||||
vorgang,
|
||||
name,
|
||||
vorname,
|
||||
email,
|
||||
gebDatum,
|
||||
index
|
||||
]
|
||||
.join("|")
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "_");
|
||||
},
|
||||
|
||||
internalRows() {
|
||||
const rawRows =
|
||||
this.rowsAsObjects();
|
||||
|
||||
const serviceColumns =
|
||||
this.getServiceColumns();
|
||||
|
||||
const savedState =
|
||||
this.getSavedState();
|
||||
|
||||
return rawRows.map((rawRow, index) => {
|
||||
const id =
|
||||
this.createPersonId(rawRow, index);
|
||||
|
||||
const state =
|
||||
savedState[id] ?? {};
|
||||
|
||||
const bookedServices =
|
||||
serviceColumns.filter(column =>
|
||||
this.isBooked(rawRow[column])
|
||||
);
|
||||
|
||||
return {
|
||||
id,
|
||||
|
||||
vorgang:
|
||||
this.cleanText(
|
||||
rawRow["Vorgang"]
|
||||
),
|
||||
|
||||
name:
|
||||
this.cleanText(
|
||||
rawRow["Name"]
|
||||
),
|
||||
|
||||
vorname:
|
||||
this.cleanText(
|
||||
rawRow["Vorname"]
|
||||
),
|
||||
|
||||
email:
|
||||
this.cleanText(
|
||||
rawRow["E-Mail"] ??
|
||||
rawRow["Email"]
|
||||
),
|
||||
|
||||
gebDatum:
|
||||
this.formatExcelDate(
|
||||
rawRow["Geb.-Datum"]
|
||||
),
|
||||
|
||||
zimmer:
|
||||
state.zimmer ??
|
||||
this.cleanText(
|
||||
rawRow["Zus_Wunsch"]
|
||||
),
|
||||
|
||||
schluessel:
|
||||
Number(
|
||||
state.schluessel ?? 0
|
||||
),
|
||||
|
||||
schluesselRetour:
|
||||
Boolean(
|
||||
state.schluesselRetour ??
|
||||
false
|
||||
),
|
||||
|
||||
leistungenListe:
|
||||
bookedServices,
|
||||
|
||||
leistungen:
|
||||
bookedServices.join(" · "),
|
||||
|
||||
skipassnummer:
|
||||
state.skipassnummer ??
|
||||
this.cleanText(
|
||||
rawRow["Skipassnummer"]
|
||||
),
|
||||
|
||||
notiz:
|
||||
state.notiz ?? "",
|
||||
|
||||
stirnlampe:
|
||||
Number(
|
||||
state.stirnlampe ?? 0
|
||||
),
|
||||
|
||||
stirnlampeRetour:
|
||||
Boolean(
|
||||
state.stirnlampeRetour ??
|
||||
false
|
||||
),
|
||||
|
||||
nachbuchungen:
|
||||
Array.isArray(
|
||||
state.nachbuchungen
|
||||
)
|
||||
? state.nachbuchungen
|
||||
: [],
|
||||
|
||||
status:
|
||||
state.status ?? "offen",
|
||||
|
||||
reiseStatus:
|
||||
state.reiseStatus ?? "aktiv",
|
||||
|
||||
checkedIn:
|
||||
Boolean(
|
||||
state.checkedIn ??
|
||||
false
|
||||
),
|
||||
|
||||
checkedInAt:
|
||||
state.checkedInAt ?? "",
|
||||
|
||||
checkedInBy:
|
||||
state.checkedInBy ?? ""
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
vorgangOptions() {
|
||||
const vorgaenge = [
|
||||
...new Set(
|
||||
this.internalRows()
|
||||
.map(row => row.vorgang)
|
||||
.filter(Boolean)
|
||||
)
|
||||
].sort((a, b) =>
|
||||
a.localeCompare(
|
||||
b,
|
||||
"de",
|
||||
{
|
||||
numeric: true
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return [
|
||||
{
|
||||
label: "Alle Gruppen",
|
||||
value: this.ALL_VALUE
|
||||
},
|
||||
...vorgaenge.map(vorgang => ({
|
||||
label: vorgang,
|
||||
value: vorgang
|
||||
}))
|
||||
];
|
||||
},
|
||||
|
||||
leistungOptions() {
|
||||
const services = [
|
||||
...new Set(
|
||||
this.internalRows()
|
||||
.flatMap(row =>
|
||||
row.leistungenListe ?? []
|
||||
)
|
||||
.filter(Boolean)
|
||||
)
|
||||
].sort((a, b) =>
|
||||
a.localeCompare(b, "de")
|
||||
);
|
||||
|
||||
return [
|
||||
{
|
||||
label: "Alle Leistungen",
|
||||
value: this.ALL_VALUE
|
||||
},
|
||||
...services.map(service => ({
|
||||
label: service,
|
||||
value: service
|
||||
}))
|
||||
];
|
||||
},
|
||||
|
||||
filteredInternalRows() {
|
||||
let rows = [
|
||||
...this.internalRows()
|
||||
];
|
||||
|
||||
/*
|
||||
* Suche
|
||||
*/
|
||||
const searchText =
|
||||
this.cleanText(
|
||||
inpSuche.text
|
||||
).toLowerCase();
|
||||
|
||||
if (searchText) {
|
||||
rows = rows.filter(row => {
|
||||
const searchableText = [
|
||||
row.vorgang,
|
||||
row.name,
|
||||
row.vorname,
|
||||
row.email,
|
||||
row.gebDatum,
|
||||
row.zimmer,
|
||||
row.skipassnummer,
|
||||
row.leistungen
|
||||
]
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
|
||||
return searchableText.includes(
|
||||
searchText
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Vorgangs-/Gruppenfilter
|
||||
*/
|
||||
const selectedVorgang =
|
||||
selVorgang.selectedOptionValue ||
|
||||
this.ALL_VALUE;
|
||||
|
||||
if (
|
||||
selectedVorgang !==
|
||||
this.ALL_VALUE
|
||||
) {
|
||||
rows = rows.filter(row =>
|
||||
row.vorgang ===
|
||||
String(selectedVorgang)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check-in-Filter
|
||||
*/
|
||||
const selectedCheckin =
|
||||
selCheckin.selectedOptionValue ||
|
||||
this.ALL_VALUE;
|
||||
|
||||
if (
|
||||
selectedCheckin === "checked"
|
||||
) {
|
||||
rows = rows.filter(row =>
|
||||
row.checkedIn === true
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
selectedCheckin === "pending"
|
||||
) {
|
||||
rows = rows.filter(row =>
|
||||
row.checkedIn === false
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reisestatusfilter
|
||||
*/
|
||||
const selectedReiseStatus =
|
||||
selReiseStatus.selectedOptionValue ||
|
||||
this.ALL_VALUE;
|
||||
|
||||
if (
|
||||
selectedReiseStatus !==
|
||||
this.ALL_VALUE
|
||||
) {
|
||||
rows = rows.filter(row =>
|
||||
row.reiseStatus ===
|
||||
selectedReiseStatus
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Leistungsfilter
|
||||
*/
|
||||
const selectedLeistung =
|
||||
selLeistung.selectedOptionValue ||
|
||||
this.ALL_VALUE;
|
||||
|
||||
if (
|
||||
selectedLeistung !==
|
||||
this.ALL_VALUE
|
||||
) {
|
||||
rows = rows.filter(row =>
|
||||
row.leistungenListe.includes(
|
||||
selectedLeistung
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return rows;
|
||||
},
|
||||
|
||||
filteredRows() {
|
||||
return this.filteredInternalRows()
|
||||
.map(row => ({
|
||||
id:
|
||||
row.id,
|
||||
|
||||
Vorgang:
|
||||
row.vorgang,
|
||||
|
||||
Name:
|
||||
row.name,
|
||||
|
||||
Vorname:
|
||||
row.vorname,
|
||||
|
||||
"E-Mail":
|
||||
row.email,
|
||||
|
||||
"Geb.-Datum":
|
||||
row.gebDatum,
|
||||
|
||||
Zimmer:
|
||||
row.zimmer,
|
||||
|
||||
Schlüssel:
|
||||
row.schluessel,
|
||||
|
||||
"Schlüssel retour":
|
||||
row.schluesselRetour,
|
||||
|
||||
"Skipass / Leistungen":
|
||||
row.leistungen,
|
||||
|
||||
Skipassnummer:
|
||||
row.skipassnummer,
|
||||
|
||||
Notiz:
|
||||
row.notiz,
|
||||
|
||||
Stirnlampe:
|
||||
row.stirnlampe,
|
||||
|
||||
"Stirnlampe retour":
|
||||
row.stirnlampeRetour,
|
||||
|
||||
Nachbuchungen:
|
||||
row.nachbuchungen.length,
|
||||
|
||||
Status:
|
||||
row.status,
|
||||
|
||||
Reisestatus:
|
||||
row.reiseStatus,
|
||||
|
||||
Eingecheckt:
|
||||
row.checkedIn,
|
||||
|
||||
"Check-in Zeitpunkt":
|
||||
row.checkedInAt,
|
||||
|
||||
"Check-in Benutzer":
|
||||
row.checkedInBy
|
||||
}));
|
||||
},
|
||||
|
||||
stats() {
|
||||
const rows =
|
||||
this.internalRows();
|
||||
|
||||
return {
|
||||
gesamt:
|
||||
rows.length,
|
||||
|
||||
eingecheckt:
|
||||
rows.filter(row =>
|
||||
row.checkedIn === true
|
||||
).length,
|
||||
|
||||
ausstehend:
|
||||
rows.filter(row =>
|
||||
row.checkedIn === false
|
||||
).length,
|
||||
|
||||
gruppen:
|
||||
new Set(
|
||||
rows
|
||||
.map(row => row.vorgang)
|
||||
.filter(Boolean)
|
||||
).size
|
||||
};
|
||||
},
|
||||
|
||||
async savePersonState(
|
||||
personId,
|
||||
changes
|
||||
) {
|
||||
if (!personId) {
|
||||
showAlert(
|
||||
"Teilnehmer-ID fehlt.",
|
||||
"error"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const currentState = {
|
||||
...this.getSavedState()
|
||||
};
|
||||
|
||||
currentState[personId] = {
|
||||
...(currentState[personId] ?? {}),
|
||||
...changes,
|
||||
|
||||
updatedAt:
|
||||
new Date().toISOString(),
|
||||
|
||||
updatedBy:
|
||||
appsmith.user?.email ||
|
||||
"lokaler Benutzer"
|
||||
};
|
||||
|
||||
await storeValue(
|
||||
"checkinState",
|
||||
currentState,
|
||||
true
|
||||
);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async toggleCheckin(tableRow) {
|
||||
if (!tableRow?.id) {
|
||||
showAlert(
|
||||
"Teilnehmer konnte nicht ermittelt werden.",
|
||||
"error"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const person =
|
||||
this.internalRows().find(row =>
|
||||
row.id === tableRow.id
|
||||
);
|
||||
|
||||
if (!person) {
|
||||
showAlert(
|
||||
"Teilnehmer wurde nicht gefunden.",
|
||||
"error"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const newCheckedIn =
|
||||
!person.checkedIn;
|
||||
|
||||
await this.savePersonState(
|
||||
person.id,
|
||||
{
|
||||
checkedIn:
|
||||
newCheckedIn,
|
||||
|
||||
checkedInAt:
|
||||
newCheckedIn
|
||||
? new Date().toISOString()
|
||||
: "",
|
||||
|
||||
checkedInBy:
|
||||
newCheckedIn
|
||||
? (
|
||||
appsmith.user?.email ||
|
||||
"lokaler Benutzer"
|
||||
)
|
||||
: ""
|
||||
}
|
||||
);
|
||||
|
||||
showAlert(
|
||||
newCheckedIn
|
||||
? `${person.vorname} ${person.name} wurde eingecheckt.`
|
||||
: `Check-in von ${person.vorname} ${person.name} wurde aufgehoben.`,
|
||||
newCheckedIn
|
||||
? "success"
|
||||
: "warning"
|
||||
);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async saveUpdatedRow(updatedRow) {
|
||||
if (!updatedRow?.id) {
|
||||
showAlert(
|
||||
"Die bearbeitete Person konnte nicht ermittelt werden.",
|
||||
"error"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const person =
|
||||
this.internalRows().find(row =>
|
||||
row.id === updatedRow.id
|
||||
);
|
||||
|
||||
if (!person) {
|
||||
showAlert(
|
||||
"Teilnehmer wurde nicht gefunden.",
|
||||
"error"
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const schluesselValue =
|
||||
Number(updatedRow["Schlüssel"]);
|
||||
|
||||
const stirnlampeValue =
|
||||
Number(updatedRow["Stirnlampe"]);
|
||||
|
||||
await this.savePersonState(
|
||||
person.id,
|
||||
{
|
||||
zimmer:
|
||||
this.cleanText(
|
||||
updatedRow["Zimmer"] ??
|
||||
person.zimmer
|
||||
),
|
||||
|
||||
schluessel:
|
||||
Number.isFinite(schluesselValue)
|
||||
? schluesselValue
|
||||
: person.schluessel,
|
||||
|
||||
schluesselRetour:
|
||||
Boolean(
|
||||
updatedRow["Schlüssel retour"] ??
|
||||
person.schluesselRetour
|
||||
),
|
||||
|
||||
skipassnummer:
|
||||
this.cleanText(
|
||||
updatedRow["Skipassnummer"] ??
|
||||
person.skipassnummer
|
||||
),
|
||||
|
||||
notiz:
|
||||
this.cleanText(
|
||||
updatedRow["Notiz"] ??
|
||||
person.notiz
|
||||
),
|
||||
|
||||
stirnlampe:
|
||||
Number.isFinite(stirnlampeValue)
|
||||
? stirnlampeValue
|
||||
: person.stirnlampe,
|
||||
|
||||
stirnlampeRetour:
|
||||
Boolean(
|
||||
updatedRow["Stirnlampe retour"] ??
|
||||
person.stirnlampeRetour
|
||||
),
|
||||
|
||||
status:
|
||||
this.cleanText(
|
||||
updatedRow["Status"] ??
|
||||
person.status
|
||||
),
|
||||
|
||||
reiseStatus:
|
||||
this.cleanText(
|
||||
updatedRow["Reisestatus"] ??
|
||||
person.reiseStatus
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
showAlert(
|
||||
"Änderungen gespeichert.",
|
||||
"success"
|
||||
);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async resetCheckinState() {
|
||||
await removeValue(
|
||||
"checkinState"
|
||||
);
|
||||
|
||||
showAlert(
|
||||
"Gespeicherte Check-in-Daten wurden zurückgesetzt.",
|
||||
"success"
|
||||
);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
async checkinButtonClick() {
|
||||
return await this.toggleCheckin(
|
||||
Teilnehmer.triggeredRow
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"gitSyncId": "6a61e887eeb7b478efb4d43d_7ee6ec8e-5d2f-4f4a-95ca-2dd087fa1a1d",
|
||||
"id": "Page1_CheckinData",
|
||||
"unpublishedCollection": {
|
||||
"name": "CheckinData",
|
||||
"pageId": "Page1",
|
||||
"pluginId": "js-plugin",
|
||||
"pluginType": "JS",
|
||||
"variables": [
|
||||
{
|
||||
"name": "ALL_VALUE",
|
||||
"value": "\"__ALL__\""
|
||||
},
|
||||
{
|
||||
"name": "CORE_COLUMNS",
|
||||
"value": "[\"Vorgang\", \"Name\", \"Vorname\", \"E-Mail\", \"Email\", \"Geb.-Datum\", \"Zus_Wunsch\", \"Skipassnummer\"]"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user