actived menu editing

the last ui page that needed to be added was managing the main
navigation menu for rendered pages, so that's been turned on. menu
items can be added by pinning pages to the menu when editing them and
can be removed by unpinning them or deleting them from the navigation
edit ui

it touched quite a few systems so all of those classes needed to be
edited as well tweaking the front end script to work with the new
modular script format
This commit is contained in:
ro 2024-03-22 14:35:44 -06:00
parent 989a4c7b69
commit 3c6322ec12
No known key found for this signature in database
GPG key ID: 29B551CDBD4D3B50
13 changed files with 195 additions and 22 deletions

View file

@ -30,4 +30,11 @@ class SettingsAPIController extends Controller
$result = $this->settings->sync($body);
return response()->json($result)->header('Content-Type', 'application/json');
}
public function navSync(Request $request)
{
$body = json_decode($request->getContent());
$result = $this->settings->navSync($body);
return response()->json($result)->header('Content-Type', 'application/json');
}
}

View file

@ -84,6 +84,11 @@ class IndexController extends Controller
]);
}
public function navigation()
{
return view('back.navigation', $this->sort->navigation());
}
public function settings()
{
return view('back.settings', $this->sort->settings());

View file

@ -26,11 +26,11 @@ class FipamoServiceProvider extends ServiceProvider
{
//services
$this->app->bind(SettingsService::class, function ($app) {
return new SettingsService(new DocService());
return new SettingsService(new DocService(), new ContentService());
});
$this->app->bind(AuthService::class, function ($app) {
return new AuthService(new SettingsService(new DocService()));
return new AuthService(new SettingsService(new DocService(), new ContentService()));
});
$this->app->bind(ContentService::class, function ($app) {
@ -38,7 +38,7 @@ class FipamoServiceProvider extends ServiceProvider
});
$this->app->bind(ThemeService::class, function ($app) {
return new ThemeService(new SettingsService(new DocService()));
return new ThemeService(new SettingsService(new DocService(), new ContentService()));
});
$this->app->bind(PaginateService::class, function ($app) {
@ -60,29 +60,29 @@ class FipamoServiceProvider extends ServiceProvider
$this->app->bind(RenderService::class, function ($app) {
return new RenderService(
new SortingService(
new SettingsService(new DocService()),
new SettingsService(new DocService(), new ContentService()),
new ContentService(),
new StringService(),
new ThemeService(new SettingsService(new DocService()))
new ThemeService(new SettingsService(new DocService(), new ContentService()))
),
new SettingsService(new DocService()),
new SettingsService(new DocService(), new ContentService()),
new ContentService(),
);
});
$this->app->bind(SortingService::class, function ($app) {
return new SortingService(
new SettingsService(new DocService()),
new SettingsService(new DocService(), new ContentService()),
new ContentService(),
new StringService(),
new ThemeService(new SettingsService(new DocService()))
new ThemeService(new SettingsService(new DocService(), new ContentService()))
);
});
$this->app->bind(AssetService::class, function ($app) {
return new AssetService(
new ThemeService(
new SettingsService(new DocService())
new SettingsService(new DocService(), new ContentService())
)
);
});

View file

@ -67,7 +67,6 @@ class PageRepository implements PageRepositoryInterface
public function update($page)
{
return $this->editPage($page, $this->pages->where('uuid', $page->uuid)->first(), 'update');
//hande result of page update
}
public function getGroup($num, $limit, $sort = "all")
@ -137,7 +136,7 @@ class PageRepository implements PageRepositoryInterface
//upadte settings if needed
$body->path = $path;
//Settings::updateMenu($body);
$this->settings->updateMenu($body);
//Settings::updateTags();
// if new page added, update current index in Settings file
if ($task == 'create') {

View file

@ -2,18 +2,24 @@
namespace App\Services;
use Carbon\Carbon;
use function _\find;
class SettingsService
{
protected $settings;
protected $folks;
protected $tags;
protected $docs;
protected $contents;
public function __construct(DocService $docService)
public function __construct(DocService $docService, ContentService $contentService)
{
$this->folks = json_decode(file_get_contents(env('FOLKS_PATH')), true);
$this->tags = json_decode(file_get_contents(env('TAGS_PATH')), true);
$this->docs = $docService;
$this->contents = $contentService;
}
protected function loadSettings()
@ -68,6 +74,29 @@ class SettingsService
$this->docs->writeSettings($this->settings);
}
public function updateMenu($body)
{
$settings = $this->loadSettings();
//$menu = $settings["menu"];
$item = [
'title' => $body->title,
'id' => $body->id,
'uuid' => $body->uuid,
'slug' => $body->slug,
'path' => $body->path,
];
if ($body->menu == 'true') {
if (!find($settings['menu'], ['uuid' => $item['uuid']])) {
array_push($settings['menu'], $item);
}
} else {
if (find($settings['menu'], ['uuid' => $item['uuid']])) {
pull($settings['menu'], $item);
}
}
$this->docs->writeSettings($settings);
}
public function sync($data)
{
//dd($data->global->renderOnSave);
@ -91,4 +120,75 @@ class SettingsService
return $this->docs->writeSettings($settings);
}
public function navSync($data)
{
$settings = $this->loadSettings();
$pages = $this->contents->loadAllPages();
$remove = $data->remove;
$result = [];
//if remove contains id, find nav item page and set menu to false
if ($remove != null || $remove != '') {
$page = $pages->where('uuid', $remove)->first();
$page['menu'] = 'false';
$page['published']
? ($page['published'] = 'true')
: ($page['published'] = 'false');
$page['featured']
? ($page['featured'] = 'true')
: ($page['featured'] = 'false');
$page['deleted']
? ($page['deleted'] = 'true')
: ($page['deleted'] = 'false');
$updated = Carbon::now();
$created = new Carbon($page['rawCreated']);
$page['created'] = $created->format("Y-m-d\TH:i:sP");
$page['updated'] = $updated->format("Y-m-d\TH:i:sP");
if ($page['layout'] == 'index') {
$writePath = '../content/pages/start/index.md';
} else {
$writePath = '../content/pages/' . $page['path'] . '/' . $page['slug'] . '.md';
}
try {
$object = (object) $page;
$object->imageList = $page['feature'];
$object->fileList = $page['files'];
$this->docs::writePages('write', $page['path'], $writePath, $this->docs::objectToMD($object));
} catch (\Exception $e) {
$result = [
'message' => 'Page Was Not Updated. Be cool ',
'type' => 'pageUpdateError',
'error' => $e->getMessage(),
];
return $result;
}
}
$settings['menu'] = [];
$items = $data->menu;
foreach ($items as $item) {
array_push($settings['menu'], [
'title' => $item->title,
'id' => $item->id,
'uuid' => $item->uuid,
'slug' => $item->slug,
'path' => $item->path,
]);
}
try {
$this->docs->writeSettings($settings);
$result = [
'message' => 'Navigation updated. Very slick!',
'type' => 'menuUpdated',
];
} catch (\Exception $e) {
$result = [
'message' => 'Navigation Update Error. It\'ll be ok!',
'type' => 'menuUpdateError',
];
};
return $result;
}
}

View file

@ -251,6 +251,17 @@ class SortingService
return $pageOptions;
}
public function navigation()
{
$pageOptions = [
'title' => 'Edit Navigation',
'status' => session('member') != '' ? true : false,
'menu' => $this->settings->getMenu(),
];
return $pageOptions;
}
public function settings()
{
$global = $this->settings->getGlobal();

View file

@ -7,6 +7,12 @@ svg[role="icon"] {
color: var(--secondary);
}
svg#move-menu-item {
fill: var(--secondary-highlight);
top: 8px;
position: relative;
}
button[data-render="true"] {
background: var(--primary);
}

View file

@ -7,7 +7,7 @@ article[role="navigation"] {
article[role="navigation"] > section > div.nav-item {
display: block;
width: 98%;
background: var(--white);
background: var(--secondary);
border-radius: 3px;
color: var(--secondary-highlight);
margin: 0 0 10px;

View file

@ -0,0 +1,9 @@
import Nav from './controllers/NavIndex.js';
document.addEventListener(
'DOMContentLoaded',
function () {
new Nav();
},
false
);

View file

@ -1,8 +1,8 @@
import FipamoAdminAPI, { TASK_SYNC_NAV } from '../../libraries/FipamoAdminAPI';
import NavActions from '../actions/NavActions';
import * as DataEvent from '../events/DataEvent';
import Notifications from '../ui/Notifications';
import Sortable from 'sortablejs';
import FipamoAdminAPI, { TASK_SYNC_NAV } from '../../libraries/FipamoAdminAPI.js';
import NavActions from '../actions/NavActions.js';
import * as DataEvent from '../events/DataEvent.js';
import Notifications from '../ui/Notifications.js';
import Sortable from '../vendor/sortable.core.esm.js';
const notify = new Notifications();
export default class NavIndex {
@ -49,6 +49,7 @@ export default class NavIndex {
switch (e.target.id) {
case 'remove-item':
id = e.target.getAttribute('data-id');
console.log('object', e);
new NavActions().removeItem(id);
new NavActions().syncMenu().then(data => {
data.remove = e.target.getAttribute('data-uuid');
@ -59,7 +60,7 @@ export default class NavIndex {
if (r.type == DataEvent.MENU_UPDATED) {
notify.alert(r.message, true);
} else {
notify.alert(r.message, true);
notify.alert(r.message, false);
}
});
});

View file

@ -0,0 +1,33 @@
@extends('frame')
@section('title', 'The Dash | Edit Navigation')
@section('main-content')
<article role="navigation">
<section id="nav-items">
@foreach($menu as $item)
<div id="{{ $item['id'] }}" class="nav-item" data-slug="{{ $item['slug'] }}" data-uuid="{{ $item['uuid'] }}" data-path="{{ $item['id'] }}">
<svg id="move-menu-item" role="icon">
<use id="move-menu-item" xlink:href="/assets/images/global/sprite.svg#entypo-select-arrows"/>
</svg>
<label>{{ $item['title'] }}</label>
<div id="nav-btns">
<button id="edit-item" class="nav-btn" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}" title="edit page">
<svg id="edit-item" role="icon" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}">
<use id="edit-item" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}" xlink:href="/assets/images/global/sprite.svg#entypo-edit"/>
</svg>
</button>
<button id="remove-item" class="nav-btn" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}" title="delete from menu">
<svg id="remove-item" role="icon" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}">
<use id="remove-item" data-uuid="{{ $item['uuid'] }}" data-id="{{ $item['id'] }}" xlink:href="/assets/images/global/sprite.svg#entypo-cross"/>
</svg>
</button>
</div>
</div>
@endforeach
</section>
</article>
@endsection
@section('scripting')
<script type="module" src="/assets/scripts/dash/app/EditNav.js"></script>
@endsection

View file

@ -27,3 +27,4 @@ Route::post("/v1/files", [FileUploadAPIController::class, 'upload']);
//settings
Route::put("/v1/settings/publish", [SettingsAPIController::class, 'publish']);
Route::put("/v1/settings/sync", [SettingsAPIController::class, 'sync']);
Route::put("/v1/settings/nav-sync", [SettingsAPIController::class, 'navSync']);

View file

@ -31,6 +31,7 @@ Route::group(['prefix' => 'dashboard', 'middleware' => 'member.check'], function
Route::get("/pages/{pageFilter?}/{pageNum?}", [IndexController::class, 'book']);
Route::get("/page/{mode}/{uuid}", [IndexController::class, 'page']);
Route::get("/settings", [IndexController::class, 'settings']);
Route::get("/navigation", [IndexController::class, 'navigation']);
Route::get("/logout", [AuthController::class, 'exit']);
});