add form for creating new tops
This commit is contained in:
parent
a97f9f4980
commit
3f0e2e4321
|
@ -1,7 +1,9 @@
|
||||||
# WikiJs Metabot
|
# WikiJs Metabot
|
||||||
|
|
||||||
Ein Skript was die Page-Listings auf [https://wiki.ctdo.de](https://wiki.ctdo.de)
|
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
|
## 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