You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.2 KiB
JavaScript
196 lines
5.2 KiB
JavaScript
import padliographyStore from "./PadStore.js";
|
|
|
|
export default {
|
|
setup() {
|
|
const { ref, computed, watchEffect } = Vue;
|
|
const columns = ["title", "overview", "categories", "date"];
|
|
|
|
const loaded = ref(false);
|
|
|
|
const { padStore, currentPage, baseUrl } = padliographyStore();
|
|
const newPage = ref("");
|
|
const initPage = ref("");
|
|
const pageDescription = ref("");
|
|
|
|
const initialize = function () {
|
|
fetch(`${baseUrl.value}/api/${initPage.value}/init`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
description: pageDescription.value,
|
|
}),
|
|
}).then((res) => (currentPage.value = initPage.value));
|
|
};
|
|
|
|
const edit = ref(false);
|
|
const init = ref(false);
|
|
|
|
const pads = ref([]);
|
|
|
|
const currentSort = ref("date");
|
|
const currentSortDir = ref("desc");
|
|
|
|
const categories = ref([]);
|
|
const selected = ref(new Set());
|
|
const toggle = function (tag) {
|
|
selected.value.has(tag) ? selected.value.delete(tag) : selected.value.add(tag);
|
|
};
|
|
|
|
watchEffect(() => {
|
|
fetch(`${baseUrl.value}/api/${currentPage.value}/`)
|
|
.then((res) => res.json())
|
|
.then((data) => {
|
|
pads.value = data.pads;
|
|
|
|
pads.value.map(
|
|
(pad) =>
|
|
(pad.categories = pad.categories
|
|
.split(",")
|
|
.map((category) => category.trim()))
|
|
);
|
|
|
|
categories.value = Array.from(
|
|
new Set([...pads.value.map((pad) => pad.categories)].flat())
|
|
).sort();
|
|
|
|
loaded.value = true;
|
|
});
|
|
});
|
|
const sortedPads = computed(() => {
|
|
return filteredPads.value.sort((a, b) => {
|
|
let modifier = 1;
|
|
|
|
if (currentSortDir.value === "desc") modifier = -1;
|
|
|
|
if (currentSort.value === "date") {
|
|
a[currentSort.value] = new Date(a[currentSort.value]);
|
|
b[currentSort.value] = new Date(b[currentSort.value]);
|
|
}
|
|
|
|
if (a[currentSort.value] < b[currentSort.value]) return -1 * modifier;
|
|
if (a[currentSort.value] > b[currentSort.value]) return 1 * modifier;
|
|
return 0;
|
|
});
|
|
});
|
|
|
|
const sort = function (s) {
|
|
if (s == currentSort.value) {
|
|
currentSortDir.value = currentSortDir.value === "asc" ? "desc" : "asc";
|
|
}
|
|
currentSort.value = s;
|
|
};
|
|
|
|
const filteredPads = computed(() => {
|
|
if (selected.value.size == 0) return storedPads.value;
|
|
else
|
|
return storedPads.value.filter((pad) => {
|
|
return pad.categories.some((category) => selected.value.has(category));
|
|
});
|
|
});
|
|
|
|
const storedPads = computed(() => {
|
|
return [...padStore.value, ...pads.value];
|
|
});
|
|
|
|
const formatDate = function (date) {
|
|
date = new Date(date);
|
|
return `${String(date.getDate()).padStart(2, "0")}-${String(
|
|
date.getMonth() + 1
|
|
).padStart(2, "0")}-${date.getFullYear()}`;
|
|
};
|
|
|
|
return {
|
|
pads,
|
|
columns,
|
|
currentPage,
|
|
loaded,
|
|
filteredPads,
|
|
categories,
|
|
selected,
|
|
sortedPads,
|
|
currentSort,
|
|
currentSortDir,
|
|
toggle,
|
|
sort,
|
|
formatDate,
|
|
initialize,
|
|
padStore,
|
|
storedPads,
|
|
edit,
|
|
init,
|
|
newPage,
|
|
initPage,
|
|
pageDescription,
|
|
};
|
|
},
|
|
template: `
|
|
|
|
<div class="git">
|
|
<a href="https://git.xpub.nl/kamo/pad-bis" >git</a>, <a href="https://constantvzw.org/wefts/cc4r.en.html" >CC4r</a>
|
|
</div>
|
|
|
|
<div v-if="!loaded" class='loading grow'>
|
|
Loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading etc
|
|
</div>
|
|
|
|
<div v-else>
|
|
<div class="filter">
|
|
<h2>Filter Categories</h2>
|
|
<ul>
|
|
<li :class="{active: selected.size == 0}" @click="selected.clear()">All</li>
|
|
<li v-for="tag in categories" :key="tag" @click="toggle(tag)" :class="{active: selected.has(tag)}">{{tag}}</li>
|
|
</ul>
|
|
</div>
|
|
|
|
|
|
<div class="from" v-if="!init">
|
|
Fetching pads from
|
|
<span class="editing" v-if="edit">
|
|
<input placeholder="New Page" v-model="newPage">
|
|
<button @click="edit=false, currentPage=newPage"> confirm </button>
|
|
<button @click="edit=false"> x </button>
|
|
</span>
|
|
|
|
<a v-else :href="'https://pzwiki.wdka.nl/mediadesign/Padliography/' + currentPage" target="_blank">{{currentPage}}</a>
|
|
<button class="change" v-if="!edit" @click="edit = true">change</button> <br>
|
|
|
|
</div>
|
|
|
|
<div v-if="init" class="init-form">
|
|
<input placeholder="New Page" v-model="initPage">
|
|
<input placeholder="Description" v-model="pageDescription">
|
|
<button @click="init=false, initialize()"> confirm </button>
|
|
<button @click="init=false, initPage=''"> x </button>
|
|
</div>
|
|
<button class="init" v-else @click="init = true"> Init a new Padliography</button>
|
|
|
|
|
|
|
|
|
|
<table>
|
|
<tr class="header">
|
|
<th v-for="column in columns" :class="column" @click='sort(column)'>
|
|
{{column }}
|
|
<span v-if='column == currentSort'> {{ currentSortDir == 'asc' ? '▼' : '▲'}}</span>
|
|
</th>
|
|
</tr>
|
|
<tr v-for="(pad, index) in sortedPads" key="pad.title, index" :class="pad.category">
|
|
<td class="title">
|
|
<a :href="pad.link" class='stretched' target="_blank"> {{pad.title}} </a>
|
|
</td>
|
|
<td class="overview">
|
|
<p>
|
|
{{pad.overview}}
|
|
</p>
|
|
</td>
|
|
<td class="categories">
|
|
<span class="category" v-for="category in pad.categories" :key="category">{{category}}</span>
|
|
</td>
|
|
<td class="date">{{formatDate(pad.date)}}</td>
|
|
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
`,
|
|
};
|