Skip to content

Commit

Permalink
implemented basic Execute action and ExecuteLink
Browse files Browse the repository at this point in the history
  • Loading branch information
reinvanoyen committed Jan 17, 2023
1 parent 70b7e44 commit 4b090fe
Show file tree
Hide file tree
Showing 13 changed files with 55,963 additions and 11 deletions.
4,195 changes: 4,194 additions & 1 deletion public/app.css

Large diffs are not rendered by default.

51,501 changes: 51,499 additions & 2 deletions public/app.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/app.js": "/app.js?id=5018256cfd2b5e61031b",
"/app.css": "/app.css?id=f5f48ad7d78fef6b7e2e"
"/app.js": "/app.js",
"/app.css": "/app.css"
}
8 changes: 8 additions & 0 deletions resources/js/api/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ api.modules.action = (path, params = {}) => {
return axios.get(`cmf/api/modules/${path.module}/${path.action}`, {params});
};

api.modules.get = (path, execute, params = {}) => {
return axios.get(`cmf/api/modules/${path.module}/${path.action}/${execute}`, {params});
};

api.modules.post = (path, execute, params = {}) => {
return axios.post(`cmf/api/modules/${path.module}/${path.action}/${execute}`, http.formData(params));
};

api.execute.get = (path, id, execute, params = {}) => {
return axios.get(`cmf/api/modules/${path.module}/${path.action}/${id}/${execute}`, {params});
};
Expand Down
2 changes: 2 additions & 0 deletions resources/js/components/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import TextField from "./text-field";
import NumberField from "./number-field";
import TextView from "./text-view";
import Link from "./link";
import ExecuteLink from "./execute-link";
import Stack from "./stack";
import Translatable from "./translatable";
import EnumField from "./enum-field";
Expand Down Expand Up @@ -62,6 +63,7 @@ export default {
'checkbox': Checkbox,
'boolean-view': BooleanView,
'link': Link,
'execute-link': ExecuteLink,
'stack': Stack,
'translatable': Translatable,
'section': Section,
Expand Down
1 change: 0 additions & 1 deletion resources/js/components/belongs-to-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class BelongsToField extends React.Component {
}

handleChange(value) {
console.log(value);
this.setState({value});
}

Expand Down
115 changes: 115 additions & 0 deletions resources/js/components/execute-link.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React from 'react';
import Button from "../core/ui/button";
import UiLink from "../core/ui/link";
import api from "../api/api";
import util from "../core/ui/util";
import path from "../state/path";
import Overlay from "../core/ui/overlay";
import Window from "../core/ui/window";
import Form from "../core/ui/form";
import components from "../rendering/components";
import ReactDOM from "react-dom";

class ExecuteLink extends React.Component {

static defaultProps = {
path: {},
data: {},
action: '',
components: [],
notification: 'Success'
};

constructor(props) {
super(props);

this.state = {
formErrors: {},
isOpen: false
};

this.widgetMountEl = null;
this.formRef = React.createRef();
}

close() {
this.widgetMountEl.remove();
}

open() {
this.widgetMountEl = document.body.appendChild(document.createElement('div'));
ReactDOM.render(this.renderAskWidget(), this.widgetMountEl);
}

redirect(response) {
path.handleRedirect(this.props, {id: response.data.id});
}

handleClick() {
if (this.props.components.length) {
this.open();
return;
}

this.execute();
}

execute(data) {

this.close();

// Add the id to the data first
data.id = this.props.data.id || null;

let path = { ...this.props.path, action: this.props.action };

// Load the data from the backend (with id as param)
api.modules.post(path,'handle', data).then(response => {
util.notify(this.props.notification);
this.redirect(response.data);
});
}

renderAskComponents() {
return components.renderComponents(this.props.components, {}, this.props.path);
}

renderAskWidget() {
return (
<Overlay>
<Window title={this.props.text} style={'modal'} closeable={true} onClose={this.close.bind(this)}>
<Form
ref={this.formRef}
errors={this.state.formErrors}
realForm={false}
onSubmit={this.execute.bind(this)}
submitButtonText={'Submit'}
>
{this.renderAskComponents()}
</Form>
</Window>
</Overlay>
);
}

renderLink() {
if (this.props.style) {
return (
<Button style={this.props.style} text={this.props.text} onClick={this.handleClick.bind(this)} />
);
}
return <UiLink onClick={this.handleClick.bind(this)} text={this.props.text} />;
}

render() {
if (this.props.style) {
return (
<Button style={this.props.style} text={this.props.text} onClick={this.handleClick.bind(this)} />
);
}

return <UiLink onClick={this.handleClick.bind(this)} text={this.props.text} />;
}
}

export default ExecuteLink;
2 changes: 1 addition & 1 deletion resources/js/state/path.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default {

this.goBack();

} else {
} else if (props.redirect) {

// @TODO parse path, so we can also go to other modules

Expand Down
11 changes: 7 additions & 4 deletions resources/sass/cmf/core/ui/_window.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@
z-index: 9999;
top: 50%;
left: 50%;
margin-left: -30vw;
margin-top: -$window-modal-height / 2;
transform: translateX(-50%) translateY(-50%);
width: 60vw;
max-width: initial;
}

@include modifier(wide)
{
width: 80vw;
margin-left: -40vw;
}

@include modifier(fixed-size)
Expand Down Expand Up @@ -75,10 +73,15 @@

@include block-modifier(modal)
{
height: calc($window-modal-height - $window-header-height * 2);
overflow-y: scroll;
padding-bottom: $rule / 2;
margin-bottom: 0;
max-height: calc($window-modal-height - $window-header-height * 2);
}

@include block-modifier(wide)
{
height: calc($window-modal-height - $window-header-height * 2);
}

@include block-modifier(fixed-size)
Expand Down
2 changes: 2 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@

Route::get('modules', [ModulesController::class, 'index']);
Route::get('modules/{module}/{action}', [ModulesController::class, 'action']);
Route::get('modules/{module}/{action}/{execute}', [ModulesController::class, 'execute']);
Route::post('modules/{module}/{action}/{execute}', [ModulesController::class, 'execute']);

Route::get('modules/{module}/{action}/{id}/{execute}', [ComponentsController::class, 'execute'])->where('id', '[0-9]+');
Route::post('modules/{module}/{action}/{id}/{execute}', [ComponentsController::class, 'execute'])->where('id', '[0-9]+');
Expand Down
55 changes: 55 additions & 0 deletions src/Action/Execute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace ReinVanOyen\Cmf\Action;

use Illuminate\Http\Request;
use ReinVanOyen\Cmf\Http\Resources\ModelResource;

class Execute extends Action
{
/**
* @var callable $handle
*/
private $handle;

/**
* @param string $meta
* @throws \ReinVanOyen\Cmf\Exceptions\InvalidMetaException
*/
public function __construct(string $meta)
{
$this->meta($meta);
}

/**
* @return string
*/
public function type(): string
{
return 'execute';
}

/**
* @param callable $handle
* @return $this
*/
public function handle(callable $handle)
{
$this->handle = $handle;
return $this;
}

/**
* @param Request $request
* @return ModelResource
*/
public function apiHandle(Request $request)
{
$modelClass = $this->getMeta()::getModel();
$modelInstance = $modelClass::findOrFail($request->input('id'));

$result = call_user_func($this->handle, $modelInstance, $request);

return new ModelResource($modelInstance);
}
}
59 changes: 59 additions & 0 deletions src/Components/ExecuteLink.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace ReinVanOyen\Cmf\Components;

use ReinVanOyen\Cmf\Traits\CanRedirect;

class ExecuteLink extends Component
{
use CanRedirect;

/**
* Link constructor.
* @param string $text
* @param string $actionPath
*/
public function __construct(string $text, string $actionPath)
{
$this->export('text', $text);
$this->export('action', $actionPath);
}

/**
* @return string
*/
public function type(): string
{
return 'execute-link';
}

/**
* @param string $message
* @return $this
*/
public function notify(string $message)
{
$this->export('notification', $message);
return $this;
}

/**
* @param mixed $style
* @return $this
*/
public function style($style)
{
$this->export('style', $style);
return $this;
}

/**
* @param array $components
* @return $this
*/
public function ask(array $components)
{
$this->export('components', $components);
return $this;
}
}
19 changes: 19 additions & 0 deletions src/Http/Controllers/ModulesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,23 @@ public function action(Request $request, string $moduleId, string $actionId)

return ['data' => $action,];
}

/**
* @param Request $request
* @param string $moduleId
* @param string $actionId
* @param string $executeId
* @return mixed
*/
public function execute(Request $request, string $moduleId, string $actionId, string $executeId)
{
$action = $this->pathResolver->action($request, $moduleId, $actionId);
$methodName = 'api'.ucfirst($executeId);

if (! $action || ! method_exists($action, $methodName)) {
abort(404);
}

return $action->$methodName($request);
}
}

0 comments on commit 4b090fe

Please sign in to comment.