diff --git a/docs/source/development/developer_guidelines.md b/docs/source/development/developer_guidelines.md index e72193a..0014d8f 100644 --- a/docs/source/development/developer_guidelines.md +++ b/docs/source/development/developer_guidelines.md @@ -31,4 +31,5 @@ docker_development testing docs release +settings_page ``` \ No newline at end of file diff --git a/docs/source/development/release.md b/docs/source/development/release.md index 403dcb9..694af78 100644 --- a/docs/source/development/release.md +++ b/docs/source/development/release.md @@ -13,3 +13,8 @@ manual release to docker hub * `docker image tag auto-archiver bellingcat/auto-archiver:latest` * `docker push bellingcat/auto-archiver` + + +### Building the Settings Page + +The Settings page is built as part of the python-publish workflow and packaged within the app. \ No newline at end of file diff --git a/docs/source/development/settings_page.md b/docs/source/development/settings_page.md new file mode 100644 index 0000000..29c722a --- /dev/null +++ b/docs/source/development/settings_page.md @@ -0,0 +1,20 @@ +# Settings Page + +The settings page (viewable here TODO: add link), is an easy-to-use UI for users to edit their auto-archiver settings. + +The single-file app is built using React and vite. To get started developing the package, follow these steps: + +1. Make sure you have Node v22 installed. + +```{note} Tip: if you don't have node installed: + +Use `nvm` to manage your node installations. Use: +`curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash` to install `nvm` and then `nvm i 22` to install Node v22 +``` + +2. Generate the `schema.json` file for the currently installed modules using `python scripts/generate_settings_schema.py` +3. Go to the settings folder `cd scripts/settings/` and build your environment with `npm i` +4. Run a development version of the page with `npm run dev` +5. Build a release version of the page with `npm run build` + +A release version creates a single-file app called `dist/index.html` \ No newline at end of file diff --git a/scripts/generate_settings_page.py b/scripts/generate_settings_schema.py similarity index 91% rename from scripts/generate_settings_page.py rename to scripts/generate_settings_schema.py index cb3d452..e04e404 100644 --- a/scripts/generate_settings_page.py +++ b/scripts/generate_settings_schema.py @@ -1,4 +1,5 @@ import json +import os from auto_archiver.core.module import ModuleFactory from auto_archiver.core.consts import MODULE_TYPES @@ -36,6 +37,7 @@ output_schame = { 'module_types': MODULE_TYPES, } -output_file = 'schema.json' +current_file_dir = os.path.dirname(os.path.abspath(__file__)) +output_file = os.path.join(current_file_dir, 'settings/src/schema.json') with open(output_file, 'w') as file: json.dump(output_schame, file, indent=4, cls=SchemaEncoder) \ No newline at end of file diff --git a/scripts/settings/package.json b/scripts/settings/package.json index aec7706..fc7bb7b 100644 --- a/scripts/settings/package.json +++ b/scripts/settings/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc && vite build", + "build": "vite build", "preview": "vite preview" }, "dependencies": { diff --git a/scripts/settings/src/App.tsx b/scripts/settings/src/App.tsx index 1b12ba9..ab1caeb 100644 --- a/scripts/settings/src/App.tsx +++ b/scripts/settings/src/App.tsx @@ -21,6 +21,8 @@ import { rectSortingStrategy } from "@dnd-kit/sortable"; +import type { DragStartEvent, DragEndEvent, UniqueIdentifier } from "@dnd-kit/core"; + import { modules, steps, module_types } from './schema.json'; import { @@ -32,7 +34,16 @@ import Grid from '@mui/material/Grid2'; import { parseDocument, Document } from 'yaml' import StepCard from './StepCard'; -function FileDrop({ setYamlFile }) { +// create a Typescript interface for module +interface Module { + name: string; + description: string; + configs: object; + manifest: object; +} + + +function FileDrop({ setYamlFile }: { setYamlFile: React.Dispatch> }) { const [showError, setShowError] = useState(false); const [label, setLabel] = useState("Drag and drop your orchestration.yaml file here, or click to select a file."); @@ -46,9 +57,9 @@ function FileDrop({ setYamlFile }) { } let reader = new FileReader(); reader.onload = function(e) { - let contents = e.target.result; + let contents = e.target ? e.target.result : ''; try { - let document = parseDocument(contents); + let document = parseDocument(contents as string); if (document.errors.length > 0) { // not a valid yaml file setShowError(true); @@ -79,8 +90,8 @@ function FileDrop({ setYamlFile }) { } function ModuleTypes({ stepType, setEnabledModules, enabledModules, configValues }: { stepType: string, setEnabledModules: any, enabledModules: any, configValues: any }) { - const [showError, setShowError] = useState(false); - const [activeId, setActiveId] = useState(null); + const [showError, setShowError] = useState(false); + const [activeId, setActiveId] = useState(); const [items, setItems] = useState([]); useEffect(() => { @@ -121,17 +132,17 @@ function ModuleTypes({ stepType, setEnabledModules, enabledModules, configValues }) ); - const handleDragStart = (event) => { + const handleDragStart = (event: DragStartEvent) => { setActiveId(event.active.id); }; - const handleDragEnd = (event) => { - setActiveId(null); + const handleDragEnd = (event: DragEndEvent) => { + setActiveId(undefined); const { active, over } = event; - if (active.id !== over.id) { - const oldIndex = items.indexOf(active.id); - const newIndex = items.indexOf(over.id); + if (active.id !== over?.id) { + const oldIndex = items.indexOf(active.id as string); + const newIndex = items.indexOf(over?.id as string); let newArray = arrayMove(items, oldIndex, newIndex); // set it also on steps