diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..ffff2db
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,36 @@
+# EditorConfig Configurtaion file, for more details see:
+# http://EditorConfig.org
+# EditorConfig is a convention description, that could be interpreted
+# by multiple editors to enforce common coding conventions for specific
+# file types
+
+# top-most EditorConfig file:
+# Will ignore other EditorConfig files in Home directory or upper tree level.
+root = true
+
+
+[*] # For All Files
+# Unix-style newlines with a newline ending every file
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+# Set default charset
+charset = utf-8
+# Indent style default
+indent_style = space
+# Max Line Length - a hard line wrap, should be disabled
+max_line_length = off
+
+[*.{py,cfg,ini}]
+# 4 space indentation
+indent_size = 4
+
+[*.{html,dtml,pt,zpt,xml,zcml,js,jsx,json,less,css,yaml,yml}]
+# 2 space indentation
+indent_size = 2
+
+[{Makefile,.gitmodules}]
+# Tab indentation (no size specified, but view as 4 spaces)
+indent_style = tab
+indent_size = unset
+tab_width = unset
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000..192ea8b
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,2 @@
+CHANGELOG.md
+README.md
diff --git a/.project.eslintrc.js b/.project.eslintrc.js
new file mode 100644
index 0000000..6e39257
--- /dev/null
+++ b/.project.eslintrc.js
@@ -0,0 +1,50 @@
+const fs = require('fs');
+const path = require('path');
+
+const projectRootPath = fs.realpathSync('./project'); // __dirname
+const packageJson = require(path.join(projectRootPath, 'package.json'));
+
+let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
+
+let configFile;
+if (fs.existsSync(`${this.projectRootPath}/tsconfig.json`))
+ configFile = `${this.projectRootPath}/tsconfig.json`;
+else if (fs.existsSync(`${this.projectRootPath}/jsconfig.json`))
+ configFile = `${this.projectRootPath}/jsconfig.json`;
+
+if (configFile) {
+ const jsConfig = require(configFile).compilerOptions;
+ const pathsConfig = jsConfig.paths;
+ if (pathsConfig['@plone/volto'])
+ voltoPath = `./${jsConfig.baseUrl}/${pathsConfig['@plone/volto'][0]}`;
+}
+
+const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
+const reg = new AddonConfigurationRegistry(projectRootPath);
+
+// Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
+const addonAliases = Object.keys(reg.packages).map((o) => [
+ o,
+ reg.packages[o].modulePath,
+]);
+
+module.exports = {
+ extends: `${voltoPath}/.eslintrc`,
+ settings: {
+ 'import/resolver': {
+ alias: {
+ map: [
+ ['@plone/volto', '@plone/volto/src'],
+ ...addonAliases,
+ ['@package', `${__dirname}/src`],
+ ['@root', `${__dirname}/src`],
+ ['~', `${__dirname}/src`],
+ ],
+ extensions: ['.js', '.jsx', '.json'],
+ },
+ 'babel-plugin-root-import': {
+ rootPathSuffix: 'src',
+ },
+ },
+ },
+};
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d65dffd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,67 @@
+# Yeoman Volto App development
+
+### Defensive settings for make:
+# https://tech.davis-hansson.com/p/make/
+SHELL:=bash
+.ONESHELL:
+.SHELLFLAGS:=-xeu -o pipefail -O inherit_errexit -c
+.SILENT:
+.DELETE_ON_ERROR:
+MAKEFLAGS+=--warn-undefined-variables
+MAKEFLAGS+=--no-builtin-rules
+
+# Project settings
+# Update the versions depending on your project requirements | Last Updated 2022-12-23
+DOCKER_IMAGE=plone/plone-backend:6.0
+KGS=
+TESTING_ADDONS=plone.app.robotframework==2.0.0 plone.app.testing==7.0.0
+NODEBIN = ./node_modules/.bin
+
+# Plone 5 legacy
+DOCKER_IMAGE5=plone/plone-backend:5.2.9
+KGS5=plone.restapi==8.32.6 plone.volto==4.0.0 plone.rest==2.0.0
+
+DIR=$(shell basename $$(pwd))
+ADDON ?= "@Fosten/volto-farmOS"
+
+# Recipe snippets for reuse
+
+# We like colors
+# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects
+RED=`tput setaf 1`
+GREEN=`tput setaf 2`
+RESET=`tput sgr0`
+YELLOW=`tput setaf 3`
+
+
+# Top-level targets
+
+.PHONY: project
+project:
+ npm install -g yo
+ npm install -g @plone/generator-volto
+ npm install -g mrs-developer
+ yo @plone/volto project --addon ${ADDON} --workspace "src/addons/${DIR}" --no-interactive
+ ln -sf $$(pwd) project/src/addons/
+ cp .project.eslintrc.js .eslintrc.js
+ cd project && yarn
+ @echo "-------------------"
+ @echo "$(GREEN)Volto project is ready!$(RESET)"
+ @echo "$(RED)Now run: cd project && yarn start$(RESET)"
+
+.PHONY: all
+all: project
+
+.PHONY: start-test-backend
+start-test-backend: ## Start Test Plone Backend
+ @echo "$(GREEN)==> Start Test Plone Backend$(RESET)"
+ docker run -i --rm -e ZSERVER_HOST=0.0.0.0 -e ZSERVER_PORT=55001 -p 55001:55001 -e SITE=plone -e APPLY_PROFILES=plone.app.contenttypes:plone-content,plone.restapi:default,plone.volto:default-homepage -e CONFIGURE_PACKAGES=plone.app.contenttypes,plone.restapi,plone.volto,plone.volto.cors -e ADDONS='plone.app.robotframework plone.app.contenttypes plone.restapi plone.volto' plone ./bin/robot-server plone.app.robotframework.testing.PLONE_ROBOT_TESTING
+
+.PHONY: start-backend-docker
+start-backend-docker: ## Starts a Docker-based backend
+ @echo "$(GREEN)==> Start Docker-based Plone Backend$(RESET)"
+ docker run -it --rm --name=backend -p 8080:8080 -e SITE=Plone -e ADDONS='$(KGS)' $(DOCKER_IMAGE)
+
+.PHONY: help
+help: ## Show this help.
+ @echo -e "$$(grep -hE '^\S+:.*##' $(MAKEFILE_LIST) | sed -e 's/:.*##\s*/:/' -e 's/^\(.\+\):\(.*\)/\\x1b[36m\1\\x1b[m:\2/' | column -c2 -t -s :)"
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..2f4e1e8
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,17 @@
+module.exports = function (api) {
+ api.cache(true);
+ const presets = ['razzle/babel'];
+ const plugins = [
+ [
+ 'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work
+ {
+ messagesDir: './build/messages/',
+ },
+ ],
+ ];
+
+ return {
+ plugins,
+ presets,
+ };
+};
diff --git a/cypress.config.js b/cypress.config.js
new file mode 100644
index 0000000..08d55e6
--- /dev/null
+++ b/cypress.config.js
@@ -0,0 +1,8 @@
+const { defineConfig } = require('cypress');
+
+module.exports = defineConfig({
+ e2e: {
+ baseUrl: 'http://localhost:3000',
+ specPattern: 'cypress/tests/**/*.cy.{js,jsx}',
+ },
+});
diff --git a/cypress/.gitkeep b/cypress/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/cypress/fixtures/broccoli.jpg b/cypress/fixtures/broccoli.jpg
new file mode 100644
index 0000000..456706d
Binary files /dev/null and b/cypress/fixtures/broccoli.jpg differ
diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json
new file mode 100644
index 0000000..02e4254
--- /dev/null
+++ b/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/cypress/fixtures/file.pdf b/cypress/fixtures/file.pdf
new file mode 100644
index 0000000..ef9c798
Binary files /dev/null and b/cypress/fixtures/file.pdf differ
diff --git a/cypress/fixtures/image.png b/cypress/fixtures/image.png
new file mode 100644
index 0000000..4c109ba
Binary files /dev/null and b/cypress/fixtures/image.png differ
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 0000000..dffed25
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,17 @@
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+};
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 0000000..03fe48c
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,9 @@
+import '@plone/volto/cypress/add-commands';
+
+// Set PLONE_SITE_ID and PLONE_API_URL as cypress environment variables
+// if testing without using localhost or a site id of `plone`.
+
+// --- CUSTOM COMMANDS -------------------------------------------------------------
+Cypress.Commands.add('custom_command', () => {
+ // Custom code here...
+});
diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js
new file mode 100644
index 0000000..48912f7
--- /dev/null
+++ b/cypress/support/e2e.js
@@ -0,0 +1,14 @@
+import 'cypress-axe';
+import 'cypress-file-upload';
+import './commands';
+import { setup, teardown } from './reset-fixture';
+
+beforeEach(function () {
+ cy.log('Setting up API fixture');
+ setup();
+});
+
+afterEach(function () {
+ cy.log('Tearing down API fixture');
+ teardown();
+});
diff --git a/cypress/support/reset-fixture.js b/cypress/support/reset-fixture.js
new file mode 100644
index 0000000..a9a5fad
--- /dev/null
+++ b/cypress/support/reset-fixture.js
@@ -0,0 +1,45 @@
+function setup() {
+ const api_url = Cypress.env('API_PATH') || 'http://localhost:55001/plone';
+ cy.request({
+ method: 'POST',
+ url: `${api_url}/RobotRemote`,
+ headers: { Accept: 'text/xml', 'content-type': 'text/xml' },
+ body:
+ 'run_keywordremote_zodb_setupplone.app.robotframework.testing.PLONE_ROBOT_TESTING',
+ }).then(() => cy.log('Setting up API fixture'));
+}
+
+function teardown() {
+ const api_url = Cypress.env('API_PATH') || 'http://localhost:55001/plone';
+ cy.request({
+ method: 'POST',
+ url: `${api_url}/RobotRemote`,
+ headers: { Accept: 'text/xml', 'content-type': 'text/xml' },
+ body:
+ 'run_keywordremote_zodb_teardownplone.app.robotframework.testing.PLONE_ROBOT_TESTING',
+ }).then(() => cy.log('Tearing down API fixture'));
+}
+
+function main() {
+ const command = process.argv[2];
+ switch (command) {
+ case 'setup':
+ setup();
+ break;
+ case 'teardown':
+ teardown();
+ break;
+ default:
+ setup();
+ }
+}
+
+// This is the equivalent of `if __name__ == '__main__'` in Python :)
+if (require.main === module) {
+ main();
+}
+
+module.exports = {
+ setup,
+ teardown,
+};
diff --git a/cypress/tests/.gitkeep b/cypress/tests/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/jest-addon.config.js b/jest-addon.config.js
new file mode 100644
index 0000000..f66acd4
--- /dev/null
+++ b/jest-addon.config.js
@@ -0,0 +1,33 @@
+module.exports = {
+ testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'],
+ collectCoverageFrom: [
+ 'src/addons/**/src/**/*.{js,jsx,ts,tsx}',
+ '!src/**/*.d.ts',
+ ],
+ transformIgnorePatterns: ['node_modules/(?!(volto-slate|@plone/volto)/)'],
+ moduleNameMapper: {
+ '@plone/volto/cypress': '/node_modules/@plone/volto/cypress',
+ '@plone/volto/babel': '/node_modules/@plone/volto/babel',
+ '@plone/volto/(.*)$': '/node_modules/@plone/volto/src/$1',
+ '@package/(.*)$': '/src/$1',
+ '@root/(.*)$': '/src/$1',
+ '~/(.*)$': '/src/$1',
+ 'load-volto-addons':
+ '/node_modules/@plone/volto/jest-addons-loader.js',
+ '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
+ },
+ transform: {
+ '^.+\\.js(x)?$': 'babel-jest',
+ '^.+\\.(png)$': 'jest-file',
+ '^.+\\.(jpg)$': 'jest-file',
+ '^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js',
+ },
+ coverageThreshold: {
+ global: {
+ branches: 5,
+ functions: 5,
+ lines: 5,
+ statements: 5,
+ },
+ },
+};
diff --git a/locales/volto.pot b/locales/volto.pot
new file mode 100644
index 0000000..1b22bc0
--- /dev/null
+++ b/locales/volto.pot
@@ -0,0 +1,14 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: Plone\n"
+"POT-Creation-Date: 2021-01-29T12:34:47.097Z\n"
+"Last-Translator: Plone i18n \n"
+"Language-Team: Plone i18n \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"Language-Code: en\n"
+"Language-Name: English\n"
+"Preferred-Encodings: utf-8\n"
+"Domain: volto\n"
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..67f426f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "@Fosten/volto-farmOS",
+ "version": "0.1.0",
+ "description": "volto-farmOS: Volto add-on",
+ "main": "src/index.js",
+ "license": "MIT",
+ "keywords": [
+ "volto-addon",
+ "volto",
+ "plone",
+ "react"
+ ],
+ "scripts": {
+ "i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon"
+ },
+ "devDependencies": {
+ "@plone/scripts": "*"
+ }
+}
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..cb042f0
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,5 @@
+const applyConfig = (config) => {
+ return config;
+};
+
+export default applyConfig;