Kanga World Configuration plugin now working. Mostly. Some CSS issues.

This commit is contained in:
Scott Duensing 2022-01-06 20:28:50 -06:00
parent ad883d4669
commit 4bf0d99b44
15 changed files with 532 additions and 36 deletions

View file

@ -1,8 +1,6 @@
<?php
function kpKangaWorldConfig() {
return Data::read(__DIR__ . '/settings.json');
}
load(['KangarooPunch\KwConfig' => __DIR__ . '/classes/KwConfig.php']);
return [
@ -13,20 +11,22 @@ return [
'menu' => true,
// update and delete dialogs
'dialogs' => [
//require __DIR__ . '/dialogs/update.php',
//require __DIR__ . '/dialogs/delete.php'
require __DIR__ . '/dialogs/create.php',
require __DIR__ . '/dialogs/update.php',
require __DIR__ . '/dialogs/delete.php'
],
// dropdown with edit and delete buttons
'dropdowns' => [
//require __DIR__ . '/dropdowns/kwconfig.php'
require __DIR__ . '/dropdowns/kwconfig.php'
],
// search for settings
'searches' => [
//'products' => require __DIR__ . '/searches/kwconfig.php'
'kwconfig' => require __DIR__ . '/searches/kwconfig.php'
],
// view route
'views' => [
require __DIR__ . '/views/kwconfig.php'
require __DIR__ . '/views/kwconfig.php',
require __DIR__ . '/views/kwentry.php'
]
]

View file

@ -0,0 +1,142 @@
<?php
namespace KangarooPunch;
use Kirby\Data\Data;
use Kirby\Exception\InvalidArgumentException;
use Kirby\Exception\NotFoundException;
use Kirby\Toolkit\V;
class KwConfig
{
/**
* Creates a new entry with the given $input
* data and adds it to the json file
*
* @return bool
*/
public static function create(array $input): bool
{
// reuse the update method to create a new
// entry. If you need different logic
// here, you can easily extend it
return static::update($input);
}
/**
* Deletes a entry by product id
*
* @return bool
*/
public static function delete(string $id): bool
{
// get all entry
$kwconfig = static::list();
// remove the entry from the list
unset($kwconfig[$id]);
// write the update list to the file
return Data::write(static::file(), $kwconfig);
}
/**
* Returns the absolute path to the settings.json
* This is the place to modify if you don't want to
* store the entries in your plugin folder
* which you probably really don't want to do.
*
* @return string
*/
public static function file(): string
{
return __DIR__ . '/../settings.json';
}
/**
* Finds an entry by id and throws an exception
* if the entry cannot be found
*
* @param string $id
* @return array
*/
public static function find(string $id): array
{
$kwconfig = static::list()[$id] ?? null;
if (empty($kwconfig) === true) {
throw new NotFoundException('The entry could not be found');
}
return $kwconfig;
}
/**
* Lists all entries from the settings.json
*
* @return array
*/
public static function list(): array
{
return Data::read(static::file());
}
/**
* Lists all available entry types
*
* @return array
*/
public static function types(): array
{
return [
'config',
'number',
'string'
];
}
/**
* Updates a entries by id with the given input
* It throws an exception in case of validation issues
*
* @param string $id
* @param array $input
* @return boolean
*/
public static function update(array $input): bool
{
$kwconfig = [
'title' => $input['title'] ?? null,
'type' => $input['type'] ?? null,
'description' => $input['description'] ?? null,
'data' => $input['data'] ?? null
];
// require a title
if (V::minlength($kwconfig['title'], 1) === false) {
throw new InvalidArgumentException('The title must not be empty');
}
// make sure the title is not longer than expected
if (V::maxlength($kwconfig['title'], 255) === false) {
throw new InvalidArgumentException('The title must not be longer than 255 characters');
}
// validate the category
if (V::in($kwconfig['type'], static::types()) === false) {
throw new InvalidArgumentException('Please select a valid category');
}
// load all products
$kwconfig = static::list();
// set/overwrite the data
$kwconfig[$id] = $kwconfig;
return Data::write(static::file(), $kwconfig);
}
}
?>

View file

@ -0,0 +1,22 @@
<?php
use KangarooPunch\KwConfig;
return [
'pattern' => 'kwconfig/create',
'load' => function () {
return [
'component' => 'k-form-dialog',
'props' => [
'fields' => require __DIR__ . '/fields.php',
'submitButton' => t('create'),
]
];
},
'submit' => function () {
return KwConfig::create(get());
}
];
?>

View file

@ -0,0 +1,20 @@
<?php
use KangarooPunch\KwConfig;
return [
'pattern' => 'kwconfig/(:any)/delete',
'load' => function (string $id) {
return [
'component' => 'k-remove-dialog',
'props' => [
'text' => 'Do you really want to delete this entry?'
]
];
},
'submit' => function (string $id) {
return KwConfig::delete($id);
}
];
?>

View file

@ -0,0 +1,31 @@
<?php
use KangarooPunch\KwConfig;
use Kirby\Toolkit\A;
return [
'title' => [
'label' => 'Title',
'type' => 'text'
],
'type' => [
'label' => 'Type',
'type' => 'select',
'empty' => false,
'width' => '1/2',
'options' => A::map(KwConfig::types(), function ($type) {
return ['value' => $type, 'text' => $type];
})
],
'description' => [
'label' => 'Description',
'type' => 'textarea',
'buttons' => false
],
'price' => [
'label' => 'Value',
'type' => 'text'
]
];
?>

View file

@ -0,0 +1,23 @@
<?php
use KangarooPunch\KwConfig;
return [
'pattern' => 'kwconfig/(:any)/update',
'load' => function (string $id) {
$kwconfig = KwConfig::find($id);
return [
'component' => 'k-form-dialog',
'props' => [
'fields' => require __DIR__ . '/fields.php',
'value' => $kwconfig
]
];
},
'submit' => function (string $id) {
return KwConfig::update(get());
}
];
?>

View file

@ -0,0 +1,21 @@
<?php
return [
'pattern' => 'kwconfig/(:any)',
'action' => function (string $id) {
return [
[
'text' => 'Edit',
'icon' => 'edit',
'dialog' => 'kwconfig/' . $id . '/update'
],
[
'text' => 'Delete',
'icon' => 'trash',
'dialog' => 'kwconfig/' . $id . '/delete'
]
];
}
];
?>

View file

@ -14,11 +14,22 @@
overflow: hidden;
background: var(--color-white);
}
.k-kwconfig-name {
/* width: 8rem; */
}
.k-kwconfig-type {
width: 8rem;
/* width: 8rem; */
}
.k-kwconfig-description {
width: 50%;
}
.k-kwconfig-data {
width: 5rem;
/* width: 10rem; */
font-variant-numeric: tabular-nums;
text-align: right !important;
}
.k-kwconfig th button {
font: inherit;
text-align: left;
width: 100%;
}

View file

@ -1,15 +1,25 @@
(function() {
"use strict";
var render = function() {
var render$1 = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("k-inside", [_c("k-view", [_c("k-header", [_vm._v("Kanga World Configuration")]), _c("table", { staticClass: "k-kwconfig" }, [_c("tr", [_c("th", [_vm._v("Title")]), _c("th", { staticClass: "k-kwconfig-type" }, [_vm._v("Type")]), _c("th", [_vm._v("Description")]), _c("th", { staticClass: "k-kwconfig-data" }, [_vm._v("Value")])]), _vm._l(_vm.kwconfig, function(kwconfig, name) {
return _c("tr", { key: name }, [_c("td", [_vm._v(_vm._s(kwconfig.name))]), _c("td", { staticClass: "k-kwconfig-type" }, [_vm._v(_vm._s(kwconfig.type))]), _c("td", [_vm._v(_vm._s(kwconfig.description))]), _c("td", { staticClass: "k-kwconfig-data" }, [_vm._v(_vm._s(kwconfig.data) + " "), _c("k-options-dropdown", { attrs: { "options": "kwconfig/" + name } })], 1)]);
return _c("k-inside", [_c("k-view", [_c("k-header", [_vm._v(" Kanga World Configuration "), _c("k-button-group", { attrs: { "slot": "right" }, slot: "right" }, [_c("k-button", { attrs: { "text": "New Entry", "icon": "add" }, on: { "click": function($event) {
return _vm.$dialog("kwconfig/create");
} } })], 1)], 1), _c("table", { staticClass: "k-kwconfig" }, [_c("tr", [_c("th", { staticClass: "k-kwconfig-name" }, [_c("button", { on: { "click": function($event) {
return _vm.sortBy("name");
} } }, [_vm._v(" Name "), _vm.sort === "name" ? _c("span", { domProps: { "innerHTML": _vm._s(_vm.sortArrow) } }) : _vm._e()])]), _c("th", { staticClass: "k-kwconfig-type" }, [_c("button", { on: { "click": function($event) {
return _vm.sortBy("type");
} } }, [_vm._v(" Type "), _vm.sort === "type" ? _c("span", { domProps: { "innerHTML": _vm._s(_vm.sortArrow) } }) : _vm._e()])]), _c("th", { staticClass: "k-kwconfig-description" }, [_c("button", { on: { "click": function($event) {
return _vm.sortBy("description");
} } }, [_vm._v(" Description "), _vm.sort === "description" ? _c("span", { domProps: { "innerHTML": _vm._s(_vm.sortArrow) } }) : _vm._e()])]), _c("th", { staticClass: "k-kwconfig-data" }, [_c("button", { on: { "click": function($event) {
return _vm.sortBy("data");
} } }, [_vm._v(" Value "), _vm.sort === "data" ? _c("span", { domProps: { "innerHTML": _vm._s(_vm.sortArrow) } }) : _vm._e()])])]), _vm._l(_vm.kwconfig, function(kwconfig, name) {
return _c("tr", { key: name }, [_c("td", { staticClass: "k-kwconfig-name" }, [_vm._v(_vm._s(kwconfig.name))]), _c("td", { staticClass: "k-kwconfig-type" }, [_vm._v(_vm._s(kwconfig.type))]), _c("td", { staticClass: "k-kwconfig-description" }, [_vm._v(_vm._s(kwconfig.description))]), _c("td", { staticClass: "k-kwconfig-data" }, [_vm._v(_vm._s(kwconfig.data)), _c("k-options-dropdown", { attrs: { "options": "kwconfig/" + name } })], 1)]);
})], 2)], 1)], 1);
};
var staticRenderFns = [];
render._withStripped = true;
var staticRenderFns$1 = [];
render$1._withStripped = true;
var KwConfig_vue_vue_type_style_index_0_lang = "";
function normalizeComponent(scriptExports, render2, staticRenderFns2, functionalTemplate, injectStyles, scopeId, moduleIdentifier, shadowMode) {
var options = typeof scriptExports === "function" ? scriptExports.options : scriptExports;
@ -62,9 +72,57 @@
options
};
}
const __vue2_script$1 = {
props: {
dir: String,
sort: String,
kwconfig: Object
},
computed: {
sortArrow() {
return this.dir === "asc" ? "&darr;" : "&uarr;";
}
},
methods: {
sortBy(sort) {
let dir = "asc";
if (sort === this.sort)
dir = this.dir === "asc" ? "desc" : "asc";
this.$reload({
query: {
dir,
sort
}
});
}
}
};
const __cssModules$1 = {};
var __component__$1 = /* @__PURE__ */ normalizeComponent(__vue2_script$1, render$1, staticRenderFns$1, false, __vue2_injectStyles$1, null, null, null);
function __vue2_injectStyles$1(context) {
for (let o in __cssModules$1) {
this[o] = __cssModules$1[o];
}
}
__component__$1.options.__file = "src/components/KwConfig.vue";
var KwConfig = /* @__PURE__ */ function() {
return __component__$1.exports;
}();
var render = function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c("k-inside", [_c("k-view", [_c("k-header", [_vm._v(" " + _vm._s(_vm.kwentry.name) + " "), _c("k-button-group", { attrs: { "slot": "left" }, slot: "left" }, [_c("k-button", { attrs: { "text": "Edit", "icon": "edit" }, on: { "click": function($event) {
return _vm.$dialog("kwconfig/" + _vm.kwentry.name + "/update");
} } }), _c("k-button", { attrs: { "text": "Delete", "icon": "trash" }, on: { "click": function($event) {
return _vm.$dialog("kwconfig/" + _vm.kwentry.name + "/delete");
} } })], 1)], 1), _c("table", { staticClass: "k-kwconfig" }, [_c("tr", [_c("th", { staticClass: "k-kwconfig-type" }, [_vm._v("Type")]), _c("th", { staticClass: "k-kwconfig-description" }, [_vm._v("Description")]), _c("th", { staticClass: "k-kwconfig-data" }, [_vm._v("Value")])]), _c("tr", [_c("td", { staticClass: "k-kwconfig-type" }, [_vm._v(_vm._s(_vm.kwentry.type))]), _c("td", { staticClass: "k-kwconfig-description" }, [_vm._v(_vm._s(_vm.kwentry.description))]), _c("td", { staticClass: "k-kwconfig-data" }, [_vm._v(_vm._s(_vm.kwentry.data))])])])], 1)], 1);
};
var staticRenderFns = [];
render._withStripped = true;
const __vue2_script = {
props: {
kwconfig: Object
kwentry: Object
}
};
const __cssModules = {};
@ -74,13 +132,14 @@
this[o] = __cssModules[o];
}
}
__component__.options.__file = "src/components/KwConfig.vue";
var KwConfig = /* @__PURE__ */ function() {
__component__.options.__file = "src/components/KwEntry.vue";
var KwEntry = /* @__PURE__ */ function() {
return __component__.exports;
}();
panel.plugin("kangaroopunch/kangaworld-integration", {
components: {
"k-kwconfig-view": KwConfig
"k-kwconfig-view": KwConfig,
"k-kwentry-view": KwEntry
}
});
})();

View file

@ -0,0 +1,32 @@
<?php
use KangarooPunch\KwConfig;
return [
'label' => 'Configuration',
'icon' => 'globe',
'query' => function(string $query) {
$kwconfig = KwConfig::list();
$results = [];
foreach ($kwconfig as $kwentry) {
if ((Str::contains($kwentry['name'], $query, true) === true) ||
(Str::contains($kwentry['description'], $query, true) === true) ||
(Str::contains($kwentry['data'], $query, true) === true)) {
$results[] = [
'text' => $kwentry['name'],
'link' => '/kwconfig/' . esc($kwentry['name'], 'url'),
'image' => [
'icon' => 'globe',
'back' => 'purple-400'
]
];
}
}
return $results;
}
];
?>

View file

@ -1,21 +1,48 @@
<template>
<k-inside>
<k-view>
<k-header>Kanga World Configuration</k-header>
<k-header>
Kanga World Configuration
<k-button-group slot="right">
<k-button
text="New Entry"
icon="add"
@click="$dialog('kwconfig/create')"
/>
</k-button-group>
</k-header>
<table class="k-kwconfig">
<tr>
<th>Title</th>
<th class="k-kwconfig-type">Type</th>
<th>Description</th>
<th class="k-kwconfig-data">Value</th>
<th class="k-kwconfig-name">
<button @click="sortBy('name')">
Name
<span v-if="sort === 'name'" v-html="sortArrow"/>
</button>
</th>
<th class="k-kwconfig-type">
<button @click="sortBy('type')">
Type
<span v-if="sort === 'type'" v-html="sortArrow"/>
</button>
</th>
<th class="k-kwconfig-description">
<button @click="sortBy('description')">
Description
<span v-if="sort === 'description'" v-html="sortArrow"/>
</button>
</th>
<th class="k-kwconfig-data">
<button @click="sortBy('data')">
Value
<span v-if="sort === 'data'" v-html="sortArrow"/>
</button>
</th>
</tr>
<tr v-for="(kwconfig, name) in kwconfig" :key="name">
<td>{{ kwconfig.name }}</td>
<td class="k-kwconfig-name">{{ kwconfig.name }}</td>
<td class="k-kwconfig-type">{{ kwconfig.type }}</td>
<td>{{ kwconfig.description }}</td>
<td class="k-kwconfig-data">{{ kwconfig.data }}
<k-options-dropdown :options="'kwconfig/' + name" />
</td>
<td class="k-kwconfig-description">{{ kwconfig.description }}</td>
<td class="k-kwconfig-data">{{ kwconfig.data }}<k-options-dropdown :options="'kwconfig/' + name" /></td>
</tr>
</table>
</k-view>
@ -25,7 +52,26 @@
<script>
export default {
props: {
dir: String,
sort: String,
kwconfig: Object
},
computed: {
sortArrow() {
return this.dir === "asc" ? "&darr;" : "&uarr;";
},
},
methods: {
sortBy(sort) {
let dir = "asc";
if (sort === this.sort) dir = this.dir === "asc" ? "desc" : "asc";
this.$reload({
query: {
dir: dir,
sort: sort
},
});
}
}
};
</script>
@ -46,12 +92,23 @@ export default {
overflow: hidden;
background: var(--color-white);
}
.k-kwconfig-name {
/* width: 8rem; */
}
.k-kwconfig-type {
width: 8rem;
/* width: 8rem; */
}
.k-kwconfig-description {
width: 50%;
}
.k-kwconfig-data {
width: 5rem;
/* width: 10rem; */
font-variant-numeric: tabular-nums;
text-align: right !important;
}
.k-kwconfig th button {
font: inherit;
text-align: left;
width: 100%;
}
</style>

View file

@ -0,0 +1,41 @@
<template>
<k-inside>
<k-view>
<k-header>
{{ kwentry.name }}
<k-button-group slot="left">
<k-button
text="Edit"
icon="edit"
@click="$dialog('kwconfig/' + kwentry.name + '/update')"
/>
<k-button
text="Delete"
icon="trash"
@click="$dialog('kwconfig/' + kwentry.name + '/delete')"
/>
</k-button-group>
</k-header>
<table class="k-kwconfig">
<tr>
<th class="k-kwconfig-type">Type</th>
<th class="k-kwconfig-description">Description</th>
<th class="k-kwconfig-data">Value</th>
</tr>
<tr>
<td class="k-kwconfig-type">{{ kwentry.type }}</td>
<td class="k-kwconfig-description">{{ kwentry.description }}</td>
<td class="k-kwconfig-data">{{ kwentry.data }}</td>
</tr>
</table>
</k-view>
</k-inside>
</template>
<script>
export default {
props: {
kwentry: Object
}
};
</script>

View file

@ -1,7 +1,9 @@
import KwConfig from "./components/KwConfig.vue";
import KwEntry from "./components/KwEntry.vue";
panel.plugin("kangaroopunch/kangaworld-integration", {
components: {
"k-kwconfig-view": KwConfig
"k-kwconfig-view": KwConfig,
"k-kwentry-view": KwEntry
}
});

View file

@ -1,13 +1,23 @@
<?php
use KangarooPunch\KwConfig;
return [
'pattern' => 'kwconfig',
'action' => function () {
$sort = get('sort', 'name');
$dir = get('dir', 'asc');
$kwconfig = KwConfig::list();
$kwconfig = A::sort($kwconfig, $sort, $dir);
return [
'component' => 'k-kwconfig-view',
'props' => [
'kwconfigs' => kpKangaWorldConfig()
]
'dir' => $dir,
'sort' => $sort,
'kwconfig' => $kwconfig
],
'search' => 'kwconfig'
];
}
];

View file

@ -0,0 +1,25 @@
<?php
use KangarooPunch\KwConfig;
return [
'pattern' => 'kwconfig/(:any)',
'action' => function ($id) {
$kwentry = KwConfig::find($id);
return [
'component' => 'k-kwentry-view',
'breadcrumb' => [
[
'label' => $kwentry['name'],
'link' => 'kwconfig/' . $id
]
],
'props' => [
'kwentry' => $kwentry
]
];
}
];
?>