@retikolo/drag-drop-content-types 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # Strapi plugin drag-drop-content-types
2
+ ![drag-drop-preview](https://user-images.githubusercontent.com/37687705/191790500-f7bc7968-cf10-4448-a049-3350d96d2d8b.png)
3
+
4
+ ## ⚠THIS PLUGIN IS IN ALPHA⚠
5
+ Be warned. Breaking changes can happen. Bad things can happen. Unexpected things can happen. Woosh!
6
+
7
+ ## Install
8
+ 1. Add the plugin to the `src/plugins` directory.
9
+ 2. Add this to your `config/plugins.js` file (create it, if it doesn't exist yet):
10
+ ```js
11
+ module.exports = {
12
+ // ...
13
+ 'drag-drop-content-types': {
14
+ enabled: true,
15
+ resolve: './src/plugins/drag-drop-content-types'
16
+ }
17
+ }
18
+ ```
19
+ 3. Run `npm run build` and (re)start the app
20
+
21
+ ## Configuration
22
+ Go to `Settings` -> `Drag Drop Content Type` -> `Configuration`:
23
+ * Specify how the rank field and the corresponding title field are called in your content types. Default value are `rank` and `title`.
24
+ * Add the specified fields to your content type. With the default values this would be `title` (Text (Type: Short Text)) and `rank` (Number (Number format: integer))
25
+ * You will be rewared with the drag-dropable menu in the list view of all content types having the specified fields.
26
+
@@ -0,0 +1,18 @@
1
+ import axiosInstance from '../utils/axiosInstance';
2
+
3
+ const sortRequests = {
4
+ getTaskCount: async () => {
5
+ const data = await axiosInstance.get(`/drag-drop-content-types/count`);
6
+ return data;
7
+ },
8
+ getSettings: async () => {
9
+ const data = await axiosInstance.get(`/drag-drop-content-types/settings`);
10
+ return data;
11
+ },
12
+ setSettings: async data => {
13
+ return await axiosInstance.post(`/drag-drop-content-types/settings`, {
14
+ body: data,
15
+ });
16
+ },
17
+ };
18
+ export default sortRequests;
@@ -0,0 +1,26 @@
1
+ /**
2
+ *
3
+ * Initializer
4
+ *
5
+ */
6
+
7
+ import { useEffect, useRef } from 'react';
8
+ import PropTypes from 'prop-types';
9
+ import pluginId from '../../pluginId';
10
+
11
+ const Initializer = ({ setPlugin }) => {
12
+ const ref = useRef();
13
+ ref.current = setPlugin;
14
+
15
+ useEffect(() => {
16
+ ref.current(pluginId);
17
+ }, []);
18
+
19
+ return null;
20
+ };
21
+
22
+ Initializer.propTypes = {
23
+ setPlugin: PropTypes.func.isRequired,
24
+ };
25
+
26
+ export default Initializer;
@@ -0,0 +1,150 @@
1
+ import React, { useState, useEffect } from 'react';
2
+
3
+ import axiosInstance from '../../utils/axiosInstance';
4
+
5
+ import DragSortableList from 'react-drag-sortable'
6
+
7
+ import { SimpleMenu, MenuItem } from '@strapi/design-system/SimpleMenu';
8
+ import { IconButton } from '@strapi/design-system/IconButton';
9
+ import { Icon } from '@strapi/design-system/Icon';
10
+ import Drag from '@strapi/icons/Drag';
11
+ import Layer from '@strapi/icons/Layer';
12
+
13
+ const SortModal = () => {
14
+
15
+ const [active, setActive] = useState(false);
16
+ const [contentType, setContentType] = useState([]);
17
+ const [status, setStatus] = useState('loading');
18
+ const [settings, setSettings] = useState();
19
+
20
+ // Shorten string to prevent line break
21
+ const shortenString = (string) => {
22
+ if (string.length > 40) {
23
+ return string.substring(0, 37) + "..."
24
+ }
25
+ return string
26
+ }
27
+
28
+ // Fetch settings from configuration
29
+ const fetchSettings = async () => {
30
+ try {
31
+ const { data } = await axiosInstance.get(`drag-drop-content-types/settings`);
32
+ setSettings(data.body);
33
+ } catch (e) {
34
+ console.log(e);
35
+ }
36
+ };
37
+
38
+ // Check database if the desired fields are available
39
+ // TODO: check field integrity
40
+ const initializeContentType = async () => {
41
+ try {
42
+ if (settings){
43
+ const { data } = await axiosInstance.get(
44
+ `/content-manager/collection-types/${contentTypePath}?sort=rank:asc`
45
+ );
46
+ if (data.results.length > 0 && !!toString(data.results[0][settings.rank]) && !!data.results[0][settings.title]) {
47
+ setActive(true);
48
+ }
49
+ }
50
+ } catch (e) {
51
+ console.log(e);
52
+ setStatus('error');
53
+ }
54
+ }
55
+
56
+ // Fetch data from the database via get request
57
+ const fetchContentType = async () => {
58
+ try {
59
+ const { data } = await axiosInstance.get(
60
+ `/content-manager/collection-types/${contentTypePath}?sort=rank:asc`
61
+ );
62
+ setStatus('success');
63
+ // Iterate over all results and append them to the list
64
+ let list = [];
65
+ for (let i = 0; i < data.results.length; i++) {
66
+ list.push({
67
+ content: (<MenuItem ><Icon height={"0.6rem"} as={Drag} />&nbsp;<span title={data.results[i][settings.title]}>{shortenString(data.results[i][settings.title])}</span></MenuItem>), strapiId: data.results[i].id
68
+ });
69
+ }
70
+ setContentType(list);
71
+ } catch (e) {
72
+ console.log(e);
73
+ setStatus('error');
74
+ }
75
+ };
76
+
77
+ // Update all ranks via put request.
78
+ const updateContentType = async (sortedList) => {
79
+ try {
80
+ // Increase performance by breaking loop after last element having a rank change is updated
81
+ let rankHasChanged = false
82
+ // Iterate over all results and append them to the list
83
+ for (let i = 0; i < sortedList.length; i++) {
84
+ // Only update changed values
85
+ if (previousSortedList.length == 0 || previousSortedList[i].strapiId != sortedList[i].strapiId) {
86
+ // Update rank via put request
87
+ await axiosInstance.put(`/drag-drop-content-types/sort-update/${sortedList[i].strapiId}`, {
88
+ contentType: contentTypePath,
89
+ rank: sortedList[i].rank,
90
+ });
91
+ rankHasChanged = true;
92
+ } else if (rankHasChanged) {
93
+ break;
94
+ }
95
+ }
96
+ // Store the state of the list to increase update performance
97
+ // TODO: Currently on the first event all entries are updated,
98
+ // since there is no previous list available.
99
+ // Get an initial state when first loading page.
100
+ previousSortedList = sortedList;
101
+ setStatus('success');
102
+ } catch (e) {
103
+ console.log(e);
104
+ setStatus('error');
105
+ }
106
+ };
107
+
108
+ // Render the menu
109
+ const showMenu = () => {
110
+ if (!active) {
111
+ return
112
+ }
113
+ return (
114
+ <>
115
+ <SimpleMenu
116
+ as={IconButton}
117
+ icon={<Layer />}
118
+ onClick={() => { fetchContentType() }}
119
+ >
120
+ <DragSortableList items={contentType} moveTransitionDuration={0.3} onSort={updateContentType} type="vertical" />
121
+ </SimpleMenu>
122
+ </>
123
+ )
124
+ }
125
+
126
+ // Fetch settings on page render
127
+ useEffect(() => {
128
+ fetchSettings();
129
+ }, [])
130
+
131
+ // Update view when settings change
132
+ useEffect(() => {
133
+ initializeContentType();
134
+ }, [settings])
135
+
136
+ // Get content type from url
137
+ const paths = window.location.pathname.split('/')
138
+ const contentTypePath = paths[paths.length - 1]
139
+
140
+ // Store the drag and drop lists previous value to increase update performance
141
+ let previousSortedList = []
142
+
143
+ return (
144
+ <>
145
+ {showMenu()}
146
+ </>
147
+ );
148
+ };
149
+
150
+ export default SortModal;
@@ -0,0 +1,91 @@
1
+ import { prefixPluginTranslations } from '@strapi/helper-plugin';
2
+ import pluginPkg from '../../package.json';
3
+ import pluginId from './pluginId';
4
+ import Initializer from './components/Initializer';
5
+ import SortModal from './components/SortModal';
6
+
7
+
8
+ const name = pluginPkg.strapi.name;
9
+
10
+ export default {
11
+ register(app) {
12
+ app.createSettingSection(
13
+ {
14
+ id: pluginId,
15
+ intlLabel: {
16
+ id: `${pluginId}.plugin.name`,
17
+ defaultMessage: 'Drag Drop Content Types',
18
+ },
19
+ },
20
+ [
21
+ {
22
+ intlLabel: {
23
+ id: `${pluginId}.plugin.name`,
24
+ defaultMessage: 'Configuration',
25
+ },
26
+ id: 'settings',
27
+ to: `/settings/${pluginId}`,
28
+ Component: async () => {
29
+ return import('./pages/Settings');
30
+ },
31
+ },
32
+ ]
33
+ );
34
+ app.registerPlugin({
35
+ id: pluginId,
36
+ initializer: Initializer,
37
+ isReady: false,
38
+ name,
39
+ });
40
+ },
41
+
42
+ bootstrap(app) {
43
+ app.injectContentManagerComponent("listView", "actions", {
44
+ name: "sort-component",
45
+ Component: SortModal,
46
+ });
47
+
48
+ app.registerHook('Admin/CM/pages/ListView/inject-column-in-table', ({ displayedHeaders, layout }) => {
49
+ return {
50
+ layout,
51
+ displayedHeaders: [
52
+ ...displayedHeaders,
53
+ {
54
+ key: '__locale_key__', // Needed for the table
55
+ fieldSchema: { type: 'string' }, // Schema of the attribute
56
+ metadatas: {
57
+ label: 'Raboo', // Label of the header,
58
+ sortable: true | false // Define if the column is sortable
59
+ }, // Metadatas for the label
60
+ // Name of the key in the data we will display
61
+ name: 'locales',
62
+ // Custom renderer: props => Object.keys(props).map(key => <p key={key}>key</p>)
63
+ },
64
+ ]
65
+ }
66
+ });
67
+ },
68
+
69
+ async registerTrads({ locales }) {
70
+ const importedTrads = await Promise.all(
71
+ locales.map((locale) => {
72
+ return import(
73
+ /* webpackChunkName: "translation-[request]" */ `./translations/${locale}.json`
74
+ )
75
+ .then(({ default: data }) => {
76
+ return {
77
+ data: prefixPluginTranslations(data, pluginId),
78
+ locale,
79
+ };
80
+ })
81
+ .catch(() => {
82
+ return {
83
+ data: {},
84
+ locale,
85
+ };
86
+ });
87
+ })
88
+ );
89
+ return Promise.resolve(importedTrads);
90
+ },
91
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ *
3
+ * This component is the skeleton around the actual pages, and should only
4
+ * contain code that should be seen on all pages. (e.g. navigation bar)
5
+ *
6
+ */
7
+
8
+ import React from 'react';
9
+ import { Switch, Route } from 'react-router-dom';
10
+ import { NotFound } from '@strapi/helper-plugin';
11
+ import pluginId from '../../pluginId';
12
+
13
+ const App = () => {
14
+ return (
15
+ <div>
16
+ <Switch>
17
+ <Route path={`/plugins/${pluginId}`} component={HomePage} exact />
18
+ <Route component={NotFound} />
19
+ </Switch>
20
+ </div>
21
+ );
22
+ };
23
+
24
+ export default App;
@@ -0,0 +1,145 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ import sortRequests from '../../api/sort';
4
+
5
+ import { LoadingIndicatorPage, useNotification } from '@strapi/helper-plugin';
6
+
7
+ import { Box } from '@strapi/design-system/Box';
8
+ import { Stack } from '@strapi/design-system/Stack';
9
+ import { Button } from '@strapi/design-system/Button';
10
+ import { Grid, GridItem } from '@strapi/design-system/Grid';
11
+ import { HeaderLayout } from '@strapi/design-system/Layout';
12
+ import { ContentLayout } from '@strapi/design-system/Layout';
13
+ import { Typography } from '@strapi/design-system/Typography';
14
+ import { TextInput } from '@strapi/design-system/TextInput';
15
+ import { Tooltip } from '@strapi/design-system/Tooltip';
16
+
17
+ import Information from '@strapi/icons/Information';
18
+ import Check from '@strapi/icons/Check';
19
+
20
+ const Settings = () => {
21
+ const [settings, setSettings] = useState({});
22
+ const [isSaving, setIsSaving] = useState(false);
23
+ const [isLoading, setIsLoading] = useState(true);
24
+ const toggleNotification = useNotification();
25
+
26
+ useEffect(() => {
27
+ sortRequests.getSettings().then(res => {
28
+ setSettings(res.data.body);
29
+ setIsLoading(false);
30
+ });
31
+ }, [setSettings]);
32
+
33
+ const handleSubmit = async () => {
34
+ setIsSaving(true);
35
+ const res = await sortRequests.setSettings(settings);
36
+ setSettings(res.data.body);
37
+ setIsSaving(false);
38
+ toggleNotification({
39
+ type: 'success',
40
+ message: 'Settings successfully updated',
41
+ });
42
+ };
43
+
44
+ return (
45
+ <>
46
+ <HeaderLayout
47
+ id="title"
48
+ title="Drag Drop Content Type Config"
49
+ subtitle="Manage field values for drag-droppable entries"
50
+ primaryAction={
51
+ isLoading ? (
52
+ <></>
53
+ ) : (
54
+ <Button
55
+ onClick={handleSubmit}
56
+ startIcon={<Check />}
57
+ size="L"
58
+ disabled={isSaving}
59
+ loading={isSaving}
60
+ >
61
+ Save
62
+ </Button>
63
+ )
64
+ }
65
+ ></HeaderLayout>
66
+ {isLoading ? (
67
+ <LoadingIndicatorPage />
68
+ ) : (
69
+ <ContentLayout>
70
+ <Box
71
+ background="neutral0"
72
+ hasRadius
73
+ shadow="filterShadow"
74
+ paddingTop={6}
75
+ paddingBottom={6}
76
+ paddingLeft={7}
77
+ paddingRight={7}
78
+ >
79
+ <Stack size={3}>
80
+ <Typography>Field Names</Typography>
81
+ <Grid gap={6}>
82
+ <GridItem col={6} s={12}>
83
+ <Box padding={0}>
84
+ <TextInput
85
+ placeholder="Rank"
86
+ label="Rank Field Name"
87
+ hint="You must create a Number Field with this label and type integer in the Content-Type Builder"
88
+ name="content"
89
+ onChange={e => {
90
+ setSettings({
91
+ ...settings,
92
+ rank: e.target.value,
93
+ })
94
+ }}
95
+ value={settings.rank}
96
+ labelAction={
97
+ <Tooltip description="Field which is used for ordering content-type entries">
98
+ <button aria-label="Information about the email" style={{
99
+ border: 'none',
100
+ padding: 0,
101
+ background: 'transparent'
102
+ }}>
103
+ <Information aria-hidden={true} />
104
+ </button>
105
+ </Tooltip>
106
+ } />
107
+ </Box>;
108
+ </GridItem>
109
+ <GridItem col={6} s={12}>
110
+ <Box padding={0}>
111
+ <TextInput
112
+ placeholder="Title"
113
+ label="Title Field Name"
114
+ hint="You must create a Short Text Field with this label in the Content-Type Builder"
115
+ name="content"
116
+ onChange={e => {
117
+ setSettings({
118
+ ...settings,
119
+ title: e.target.value,
120
+ })
121
+ }}
122
+ value={settings.title}
123
+ labelAction={
124
+ <Tooltip description="Field that will show up in the drag drop menu">
125
+ <button aria-label="Information about the email" style={{
126
+ border: 'none',
127
+ padding: 0,
128
+ background: 'transparent'
129
+ }}>
130
+ <Information aria-hidden={true} />
131
+ </button>
132
+ </Tooltip>
133
+ } />
134
+ </Box>;
135
+ </GridItem>
136
+ </Grid>
137
+ </Stack>
138
+ </Box>
139
+ </ContentLayout>
140
+ )}
141
+ </>
142
+ );
143
+ };
144
+
145
+ export default Settings;
@@ -0,0 +1,5 @@
1
+ import pluginPkg from '../../package.json';
2
+
3
+ const pluginId = pluginPkg.name.replace(/^(@[^-,.][\w,-]+\/|strapi-)plugin-/i, '');
4
+
5
+ export default pluginId;
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * axios with a custom config.
3
+ */
4
+
5
+ import axios from 'axios';
6
+ import { auth } from '@strapi/helper-plugin';
7
+
8
+ const instance = axios.create({
9
+ baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
10
+ });
11
+
12
+ instance.interceptors.request.use(
13
+ async (config) => {
14
+ config.headers = {
15
+ Authorization: `Bearer ${auth.getToken()}`,
16
+ Accept: 'application/json',
17
+ 'Content-Type': 'application/json',
18
+ };
19
+
20
+ return config;
21
+ },
22
+ (error) => {
23
+ Promise.reject(error);
24
+ }
25
+ );
26
+
27
+ instance.interceptors.response.use(
28
+ (response) => response,
29
+ (error) => {
30
+ // whatever you want to do with the error
31
+ if (error.response?.status === 401) {
32
+ auth.clearAppStorage();
33
+ window.location.reload();
34
+ }
35
+
36
+ throw error;
37
+ }
38
+ );
39
+
40
+ export default instance;
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getTrad = (id) => `${pluginId}.${id}`;
4
+
5
+ export default getTrad;
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@retikolo/drag-drop-content-types",
3
+ "version": "1.0.0",
4
+ "description": "This plugin add a drag and droppable list that allows you to sort content type entries.",
5
+ "strapi": {
6
+ "name": "drag-drop-content-types",
7
+ "description": "This plugin add a drag and droppable list that allows you to sort content type entries.",
8
+ "kind": "plugin",
9
+ "displayName": "Drag Drop Content Types"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/plantagoIT/strapi-drag-drop-content-type-plugin"
14
+ },
15
+ "peerDependencies": {
16
+ "@strapi/strapi": "^4.0.0"
17
+ },
18
+ "dependencies": {
19
+ "react-drag-sortable": "^1.0.6"
20
+ },
21
+ "author": {
22
+ "name": "Aeneas Meier",
23
+ "email": "aeneas@retikolo.xyz",
24
+ "url": "https://rgb.retikolo.xyz"
25
+ },
26
+ "maintainers": [
27
+ {
28
+ "name": "Aeneas Meier",
29
+ "email": "aeneas@retikolo.xyz",
30
+ "url": "https://rgb.retikolo.xyz"
31
+ }
32
+ ],
33
+ "engines": {
34
+ "node": ">=14.19.1 <=18.x.x",
35
+ "npm": ">=6.0.0"
36
+ },
37
+ "license": "MIT"
38
+ }
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ module.exports = ({ strapi }) => {
4
+ console.log("REGISTERED DRAG AND DROP CONTENT TYPE PLUGIN")
5
+ };
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ module.exports = {
4
+ default: {},
5
+ validator() {},
6
+ };
@@ -0,0 +1,4 @@
1
+ 'use strict';
2
+
3
+
4
+ module.exports = {};
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const sort = require('./sort');
4
+
5
+ module.exports = {
6
+ sort,
7
+ };
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ // Get the store from the drag-drop plugin
4
+ function getPluginStore() {
5
+ return strapi.store({
6
+ environment: '',
7
+ type: 'plugin',
8
+ name: 'drag-drop-content-types',
9
+ });
10
+ }
11
+
12
+ // Create a default config if there is none yet
13
+ async function createDefaultConfig() {
14
+ const pluginStore = getPluginStore();
15
+ const value = {
16
+ body:{
17
+ rank: 'rank',
18
+ title: 'title',
19
+ }
20
+ };
21
+ await pluginStore.set({ key: 'settings', value });
22
+ return pluginStore.get({ key: 'settings' });
23
+ }
24
+
25
+ // Get settings from plugin store
26
+ async function getSettings() {
27
+ const pluginStore = getPluginStore();
28
+ let config = await pluginStore.get({ key: 'settings' });
29
+ if (!config) {
30
+ config = await createDefaultConfig();
31
+ }
32
+ return config;
33
+ }
34
+
35
+ // Update settings to plugin store
36
+ async function setSettings(settings) {
37
+ const value = settings;
38
+ const pluginStore = getPluginStore();
39
+ await pluginStore.set({ key: 'settings', value });
40
+ return pluginStore.get({ key: 'settings' });
41
+ }
42
+
43
+ // Update rank of specified content type
44
+ async function update(id, contentType, rank) {
45
+ return await strapi.query(contentType).update({
46
+ where: { id: id },
47
+ data: {
48
+ rank: rank,
49
+ }
50
+ });
51
+ }
52
+
53
+ module.exports = {
54
+ async getSettings(ctx) {
55
+ try {
56
+ ctx.body = await getSettings();
57
+ } catch (err) {
58
+ ctx.throw(500, err);
59
+ }
60
+ },
61
+ async setSettings(ctx) {
62
+ const { body } = ctx.request;
63
+ try {
64
+ await setSettings(body);
65
+ ctx.body = await getSettings();
66
+ } catch (err) {
67
+ ctx.throw(500, err);
68
+ }
69
+ },
70
+ async update(ctx) {
71
+ try {
72
+ ctx.body = await update(ctx.params.id, ctx.request.body.contentType, ctx.request.body.rank);
73
+ } catch (err) {
74
+ ctx.throw(500, err);
75
+ }
76
+ },
77
+ };
@@ -0,0 +1,5 @@
1
+ 'use strict';
2
+
3
+ module.exports = ({ strapi }) => {
4
+ // destroy phase
5
+ };
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ const register = require('./register');
4
+ const bootstrap = require('./bootstrap');
5
+ const destroy = require('./destroy');
6
+ const config = require('./config');
7
+ const contentTypes = require('./content-types');
8
+ const controllers = require('./controllers');
9
+ const routes = require('./routes');
10
+ const middlewares = require('./middlewares');
11
+ const policies = require('./policies');
12
+ const services = require('./services');
13
+
14
+ module.exports = {
15
+ register,
16
+ bootstrap,
17
+ destroy,
18
+ config,
19
+ controllers,
20
+ routes,
21
+ services,
22
+ contentTypes,
23
+ policies,
24
+ middlewares,
25
+ };
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = {};
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = {};
@@ -0,0 +1,12 @@
1
+ // server/register.js
2
+ 'use strict';
3
+
4
+ module.exports = ({ strapi }) => {
5
+ // Iterating on every content-types
6
+ Object.values(strapi.contentTypes).forEach(contentType => {
7
+ // If this is an api content-type
8
+ if (contentType.uid.includes('api::')) {
9
+ // Add prconfigured content types here
10
+ }
11
+ });
12
+ };
@@ -0,0 +1,7 @@
1
+ // Structure all routes in seperate files
2
+
3
+ const sort = require('./sort');
4
+
5
+ module.exports = {
6
+ sort,
7
+ };
@@ -0,0 +1,34 @@
1
+
2
+
3
+ module.exports = {
4
+ type: 'admin',
5
+ routes: [
6
+ {
7
+ method: 'GET',
8
+ path: '/settings',
9
+ handler: 'sort.getSettings',
10
+ config: {
11
+ policies: [],
12
+ auth: false,
13
+ },
14
+ },
15
+ {
16
+ method: 'POST',
17
+ path: '/settings',
18
+ handler: 'sort.setSettings',
19
+ config: {
20
+ policies: [],
21
+ auth: false,
22
+ },
23
+ },
24
+ {
25
+ method: "PUT",
26
+ path: "/sort-update/:id",
27
+ handler: "sort.update",
28
+ config: {
29
+ policies: [],
30
+ auth: false,
31
+ },
32
+ },
33
+ ],
34
+ };
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = {};
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./admin/src').default;
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ module.exports = require('./server');