add form for creating new tops
This commit is contained in:
parent
a97f9f4980
commit
3f0e2e4321
|
@ -1,7 +1,9 @@
|
|||
# WikiJs Metabot
|
||||
|
||||
Ein Skript was die Page-Listings auf [https://wiki.ctdo.de](https://wiki.ctdo.de)
|
||||
automatisch befüllt
|
||||
automatisch befüllt.
|
||||
Das Repo enthält außerdem die Konfiguration für ein kleines Topictreff-Form mit dem man neue Tops
|
||||
anlegen kann.
|
||||
|
||||
## Verwendung
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
.new-top {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 1rem 0;
|
||||
width: max-content;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.top-title {
|
||||
display: flex;
|
||||
margin-bottom: 1rem;
|
||||
width: 60ch;
|
||||
max-width: 100%;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.top-title:focus-within {
|
||||
outline: 1px solid #1976d2;
|
||||
}
|
||||
|
||||
.theme--dark .top-title:focus-within {
|
||||
outline: 1px solid #ffffff;
|
||||
}
|
||||
|
||||
.top-title-input {
|
||||
flex-grow: 1;
|
||||
max-width: unset;
|
||||
outline: none;
|
||||
padding: .5rem;
|
||||
color: #424242;
|
||||
background-color: #eceff1;
|
||||
border-radius: 0 .5rem .5rem 0;
|
||||
}
|
||||
|
||||
.theme--dark .top-title-input {
|
||||
color: #bdbdbd;
|
||||
background-color: #3b3b3b;
|
||||
}
|
||||
|
||||
.top-title-input-prefix {
|
||||
padding: 1rem .5rem 1rem 1rem;
|
||||
background-color: #607d8b;
|
||||
flex-shrink: 0;
|
||||
color: #ffffffb2;
|
||||
border-radius: .5rem 0 0 .5rem;
|
||||
}
|
||||
|
||||
.top-button {
|
||||
align-self: end
|
||||
}
|
||||
|
||||
.top-progress-spinner {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-left: .5rem;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<!-- prettier-ignore -->
|
||||
<form class="new-top theme--copy">
|
||||
<div class="top-title">
|
||||
<div class="top-title-input-prefix">
|
||||
TOP <span class="next-top-number">000</span> -
|
||||
</div>
|
||||
<input id="top-input" class="top-title-input theme--copy" placeholder="Titel"/>
|
||||
</div>
|
||||
|
||||
<blockquote id="top-error" class="is-danger" style="display: none;">
|
||||
<p>
|
||||
Fehler beim erstellen des Tops:<br>
|
||||
<span id="top-error-content"></span>
|
||||
</p>
|
||||
</blockquote>
|
||||
|
||||
<button id="top-button" class="top-button theme--copy v-btn v-btn--depressed v-btn--disabled v-size--large primary" type="button">
|
||||
<div class="v-btn__content">
|
||||
Neues TOP anlegen
|
||||
<div id="top-spinner" style="display: none;" class="top-progress-spinner v-progress-circular v-progress-circular--indeterminate">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="22 22 44 44" style="transform: rotate(0deg);">
|
||||
<circle fill="transparent" cx="44" cy="44" r="20" stroke-width="4" stroke-dasharray="125.664" stroke-dashoffset="125.66370614359172px" class="v-progress-circular__overlay">
|
||||
</circle>
|
||||
</svg>
|
||||
<div class="v-progress-circular__info"></div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</form>
|
|
@ -0,0 +1,126 @@
|
|||
<script>
|
||||
function copyTheme() {
|
||||
const appClasses = [...document.getElementById('app').classList];
|
||||
const appTheme = appClasses.find((c) => c.startsWith('theme--'));
|
||||
for (const element of document.getElementsByClassName('theme--copy')) {
|
||||
element.classList.replace('theme--copy', appTheme);
|
||||
}
|
||||
}
|
||||
|
||||
function setupForm() {
|
||||
const button = document.getElementById('top-button');
|
||||
const input = document.getElementById('top-input');
|
||||
const spinner = document.getElementById('top-spinner');
|
||||
const errorBox = document.getElementById('top-error');
|
||||
const errorContent = document.getElementById('top-error-content');
|
||||
input.oninput = () => {
|
||||
if (input.value === '') {
|
||||
button.classList.add('v-btn--disabled');
|
||||
button.disabled = true;
|
||||
} else {
|
||||
button.classList.remove('v-btn--disabled');
|
||||
button.disabled = false;
|
||||
}
|
||||
};
|
||||
button.onclick = async () => {
|
||||
button.classList.add('v-btn--disabled');
|
||||
button.disabled = true;
|
||||
input.disabled = true;
|
||||
spinner.style = '';
|
||||
errorBox.style = 'display: none;';
|
||||
try {
|
||||
await createNewTop(input.value);
|
||||
} catch (error) {
|
||||
errorBox.style = '';
|
||||
errorContent.textContent = error.message;
|
||||
}
|
||||
button.classList.remove('v-btn--disabled');
|
||||
button.disabled = false;
|
||||
input.disabled = false;
|
||||
spinner.style = 'display: none;';
|
||||
};
|
||||
}
|
||||
|
||||
async function getNextTopNumber() {
|
||||
const result = await graphql(
|
||||
'query { pages { list(tags: ["top"]) { path } } }'
|
||||
);
|
||||
const topNumbers = result.data.pages.list
|
||||
.map((page) => page.path)
|
||||
.map((path) => path.split('/'))
|
||||
.map((pathSegments) => pathSegments[pathSegments.length - 1])
|
||||
.map((lastSegment) => Number(lastSegment))
|
||||
.filter((topNumber) => !!topNumber);
|
||||
return Math.max(...topNumbers) + 1;
|
||||
}
|
||||
|
||||
async function insertNextTopNumbers() {
|
||||
const nextTopNumber = await getNextTopNumber();
|
||||
for (const element of document.getElementsByClassName('next-top-number')) {
|
||||
element.textContent = nextTopNumber;
|
||||
}
|
||||
}
|
||||
|
||||
async function createNewTop(title) {
|
||||
const nextTopNumber = await getNextTopNumber();
|
||||
const templateResult = await graphql(`
|
||||
query {
|
||||
pages {
|
||||
single(id: 477) {
|
||||
content
|
||||
description
|
||||
editor
|
||||
isPublished
|
||||
isPrivate
|
||||
locale
|
||||
tags {
|
||||
tag
|
||||
}
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
if (templateResult.errors && templateResult.errors.length !== 0) {
|
||||
throw new Error(templateResult.errors[0].message);
|
||||
}
|
||||
const template = templateResult.data.pages.single;
|
||||
template.tags = template.tags.map((tag) => tag.tag);
|
||||
template.path = `verein/topictreff/top/${nextTopNumber}`;
|
||||
template.title = `TOP ${nextTopNumber} - ${title}`;
|
||||
|
||||
const pageData = Object.entries(template)
|
||||
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
||||
.map((data) => {
|
||||
console.log(data);
|
||||
return data;
|
||||
})
|
||||
.join(', ');
|
||||
const result = await graphql(`
|
||||
mutation {
|
||||
pages {
|
||||
create(${pageData}) {
|
||||
responseResult {
|
||||
succeeded
|
||||
errorCode
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
const response = result.data.pages.create.responseResult;
|
||||
if (response.succeeded) {
|
||||
window.location = '/e/' + template.path;
|
||||
} else {
|
||||
throw new Error(response.message);
|
||||
console.log({ response });
|
||||
}
|
||||
}
|
||||
|
||||
isElementLoaded('.contents').then(() => {
|
||||
copyTheme();
|
||||
setupForm();
|
||||
insertNextTopNumbers();
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue