Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH Simplify APIs #83

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion _config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@

// Avoid creating global variables
call_user_func(function () {

});
8 changes: 0 additions & 8 deletions _config/graphql.yml

This file was deleted.

6 changes: 0 additions & 6 deletions _graphql/queries.yml

This file was deleted.

11 changes: 0 additions & 11 deletions _graphql/types.yml

This file was deleted.

2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

5 changes: 0 additions & 5 deletions client/src/boot/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
/* global document */
/* eslint-disable */
import Config from 'lib/Config';
import registerReducers from './registerReducers';
import registerComponents from './registerComponents';
import registerQueries from './registerQueries';

document.addEventListener('DOMContentLoaded', () => {
registerComponents();

registerQueries();

registerReducers();
});
10 changes: 0 additions & 10 deletions client/src/boot/registerQueries.js

This file was deleted.

44 changes: 34 additions & 10 deletions client/src/components/LinkField/LinkField.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, { Fragment, useState } from 'react';
import React, { Fragment, useState, useEffect } from 'react';
import { compose } from 'redux';
import { inject, injectGraphql, loadComponent } from 'lib/Injector';
import { inject, loadComponent } from 'lib/Injector';
import fieldHolder from 'components/FieldHolder/FieldHolder';

const LinkField = ({ id, loading, Loading, data, LinkPicker, onChange, types, linkDescription, ...props }) => {
if (loading) {
return <Loading />;
}

const LinkField = ({ id, onChange, dataStr, Loading, LinkPicker }) => {
// params id, onChange, dataStr come from entwine/JsonField.js
// params LinkPicker, Loading come from inject(['LinkPicker', 'Loading'])
const [types, setTypes] = useState([]);
const [description, setDescription] = useState(null);
const [editing, setEditing] = useState(false);
const [newTypeKey, setNewTypeKey] = useState('');

Expand All @@ -19,6 +19,32 @@ const LinkField = ({ id, loading, Loading, data, LinkPicker, onChange, types, li
onChange(event, { id, value: {} });
};

// Utility function to make a GET request to the server
const fetchData = (path, onFetched) => {
(async () => fetch(path))()
.then(response => response.json())
.then(onFetched);
};

// Request types data from server on initial load of component
useEffect(() => {
fetchData('/admin/linkfield/types', (responseJson) => setTypes(responseJson));
}, []);

// Request description of the link from the server when `editing` variable changes to false
// and on initial load of component
useEffect(() => {
if (!editing) {
const path = `/admin/linkfield/description?data=${encodeURI(dataStr)}`;
fetchData(path, (responseJson) => setDescription(responseJson.description));
}
}, [editing]);

if (types.length === 0 || description === null) {
return <Loading />;
}

const data = JSON.parse(dataStr);
const { typeKey } = data;
const type = types[typeKey];
const modalType = newTypeKey ? types[newTypeKey] : type;
Expand All @@ -31,7 +57,7 @@ const LinkField = ({ id, loading, Loading, data, LinkPicker, onChange, types, li

const linkProps = {
title,
link: type ? { type, title, description: linkDescription } : undefined,
link: type ? { type, title, description } : undefined,
onEdit: () => { setEditing(true); },
onClear,
onSelect: (key) => {
Expand Down Expand Up @@ -83,8 +109,6 @@ const stringifyData = (Component) => (({ data, value, ...props }) => {

export default compose(
inject(['LinkPicker', 'Loading']),
injectGraphql('readLinkTypes'),
stringifyData,
injectGraphql('readLinkDescription'),
fieldHolder
)(LinkField);
43 changes: 0 additions & 43 deletions client/src/state/linkDescription/readLinkDescription.js

This file was deleted.

48 changes: 0 additions & 48 deletions client/src/state/linkTypes/readLinkTypes.js

This file was deleted.

77 changes: 77 additions & 0 deletions src/Controllers/LinkFieldController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace SilverStripe\LinkField\Controllers;

use SilverStripe\Control\Controller;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\HTTPResponse_Exception;
use SilverStripe\LinkField\Type\Registry;

/**
* Endpoint for /admin/linkfield/<action>
*
* Routing to this controller is done via Extensions/LeftAndMain.php in the linkfield() method
*/
class LinkFieldController extends Controller
{
private static array $allowed_actions = [
'description',
'types',
];

/**
* Used for requests to /admin/linkfield/description?data={json}
*/
public function description(HTTPRequest $request): HTTPResponse
{
$jsonStr = $request->getVar('data');
// data will be an empty array if there is no existing link which is a valid use case
$data = json_decode($jsonStr, true);
$description = '';
if (json_last_error() !== JSON_ERROR_NONE) {
throw new HTTPResponse_Exception('data is not a valid JSON string');
}
if (array_key_exists('typeKey', $data)) {
$typeKey = $data['typeKey'];
/** @var Type $type */
$type = Registry::singleton()->byKey($typeKey);
if (!$type) {
throw new HTTPResponse_Exception('typeKey is not allowed');
}
$description = $type->generateLinkDescription($data);
}
return $this->jsonResponse([
'description' => $description
]);
}

/**
* Used for requests to /admin/linkfield/types
*/
public function types(): HTTPResponse
{
$data = [];
/** @var Type $type */
foreach (Registry::singleton()->list() as $key => $type) {
$data[$key] = [
'key' => $key,
'handlerName' => $type->LinkTypeHandlerName(),
'title' => $type->LinkTypeTile()
];
}
return $this->jsonResponse($data);
}

/**
* Create a JSON response to send back to the browser
*/
private function jsonResponse(array $data)
{
$response = $this->getOwner()->getResponse();
$jsonStr = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$response->setBody($jsonStr);
$response->addHeader('Content-type', 'application/json');
return $response;
}
}
13 changes: 13 additions & 0 deletions src/Extensions/LeftAndMain.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@

use SilverStripe\Core\Extension;
use SilverStripe\LinkField\Type\Registry;
use SilverStripe\LinkField\Controllers\LinkFieldController;

/**
* Register a new Form Schema in LeftAndMain.
*/
class LeftAndMain extends Extension
{
private static $allowed_actions = [
'linkfield',
];

public function init()
{
// Get the Link Registry to load all the JS requirements for managing Links.
Expand All @@ -22,4 +27,12 @@ public function updateClientConfig(&$clientConfig)
'schemaUrl' => $this->getOwner()->Link('methodSchema/Modals/DynamicLink'),
];
}

/**
* Route requests to /admin/linkfield to LinkFieldController
*/
public function linkfield(): LinkFieldController
{
return LinkFieldController::create();
}
}
34 changes: 0 additions & 34 deletions src/GraphQL/LinkDescriptionResolver.php

This file was deleted.

30 changes: 0 additions & 30 deletions src/GraphQL/LinkTypeResolver.php

This file was deleted.