This commit is contained in:
Martin Donnelly 2022-07-18 11:26:47 +01:00
parent 0c992449fc
commit 0b36df827b
37 changed files with 4754 additions and 2558 deletions

0
.eslintrc.json Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

0
.idea/.gitignore vendored Normal file → Executable file
View File

24
.idea/codeStyles/Project.xml Normal file → Executable file
View File

@ -9,6 +9,30 @@
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
<option name="SPACES_WITHIN_IMPORTS" value="true" />
</JSCodeStyleSettings>
<DBN-PSQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false" />
</DBN-PSQL>
<DBN-SQL>
<case-options enabled="true">
<option name="KEYWORD_CASE" value="lower" />
<option name="FUNCTION_CASE" value="lower" />
<option name="PARAMETER_CASE" value="lower" />
<option name="DATATYPE_CASE" value="lower" />
<option name="OBJECT_CASE" value="preserve" />
</case-options>
<formatting-settings enabled="false">
<option name="STATEMENT_SPACING" value="one_line" />
<option name="CLAUSE_CHOP_DOWN" value="chop_down_if_statement_long" />
<option name="ITERATION_ELEMENTS_WRAPPING" value="chop_down_if_not_single" />
</formatting-settings>
</DBN-SQL>
<codeStyleSettings language="JavaScript">
<option name="RIGHT_MARGIN" value="240" />
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />

0
.idea/codeStyles/codeStyleConfig.xml Normal file → Executable file
View File

458
.idea/dbnavigator.xml Executable file
View File

@ -0,0 +1,458 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="false" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DataExportManager">
<export-instructions>
<create-header value="true" />
<friendly-headers value="false" />
<quote-values-containing-separator value="true" />
<quote-all-values value="false" />
<value-separator value="" />
<file-name value="" />
<file-location value="" />
<scope value="GLOBAL" />
<destination value="FILE" />
<format value="EXCEL" />
<charset value="UTF-8" />
</export-instructions>
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.DatabaseFileManager">
<open-files />
</component>
<component name="DBNavigator.Project.EditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.ExecutionManager">
<retain-sticky-names value="false" />
</component>
<component name="DBNavigator.Project.MethodExecutionManager">
<method-browser />
<execution-history>
<group-entries value="true" />
<execution-inputs />
</execution-history>
<argument-values-cache />
</component>
<component name="DBNavigator.Project.ObjectDependencyManager">
<last-used-dependency-type value="INCOMING" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.ParserDiagnosticsManager">
<diagnostics-history />
</component>
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
<recently-used-interfaces />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
<enable-column-tooltip value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<tracking-columns>
<columnNames value="" />
<visible value="true" />
<editable value="false" />
</tracking-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-actions-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-actions-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="CSS" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JavaScript" enabled="true" />
<content-type name="JSON" enabled="true" />
<content-type name="JSON5" enabled="true" />
<content-type name="YAML" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
<enable-spellchecking value="true" />
<enable-reference-spellchecking value="false" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="JDBC" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
</component>
</project>

0
.idea/inspectionProfiles/Project_Default.xml Normal file → Executable file
View File

0
.idea/jsLibraryMappings.xml Normal file → Executable file
View File

0
.idea/jsLinters/eslint.xml Normal file → Executable file
View File

0
.idea/misc.xml Normal file → Executable file
View File

0
.idea/modules.xml Normal file → Executable file
View File

0
.idea/svelte_menu.iml Normal file → Executable file
View File

0
.idea/vcs.xml Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

View File

@ -1,4 +1,4 @@
#!/usr/bin/env bash
# rm -rf /home/martin/dev/menuserver/dist/*
cp -r /home/martin/dev/svelte_menu/public/* /home/martin/dev/menuserver/dist
cp -r ./public/* $HOME/dev/Apps/Menu/menuserver/dist

5103
package-lock.json generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

26
package.json Normal file → Executable file
View File

@ -7,20 +7,22 @@
"start": "sirv public"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^11.0.0",
"@rollup/plugin-node-resolve": "^7.0.0",
"eslint": "^6.8.0",
"eslint-plugin-svelte3": "^2.7.3",
"rollup": "^1.20.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"svelte": "^3.0.0"
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-node-resolve": "^13.0.4",
"eslint": "^7.32.0",
"eslint-plugin-svelte3": "^3.2.0",
"rollup": "^2.56.3",
"rollup-plugin-css-only": "^3.1.0",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-svelte": "^7.1.0",
"rollup-plugin-terser": "^7.0.2",
"svelte": "^3.42.4"
},
"dependencies": {
"axios": "^0.19.2",
"debounce": "^1.2.0",
"axios": "^0.21.1",
"debounce": "^1.2.1",
"pnpm": "^6.14.5",
"rollup-plugin-replace": "^2.2.0",
"sirv-cli": "^0.4.4"
"sirv-cli": "^1.0.14"
}
}

27
package.json.orig Executable file
View File

@ -0,0 +1,27 @@
{
"name": "svelte-app",
"version": "1.0.0",
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^13.0.0",
"@rollup/plugin-node-resolve": "^8.1.0",
"eslint": "^7.3.1",
"eslint-plugin-svelte3": "^2.7.3",
"rollup": "^2.18.0",
"rollup-plugin-livereload": "^1.3.0",
"rollup-plugin-svelte": "^5.2.3",
"rollup-plugin-terser": "^6.1.0",
"svelte": "^3.23.2"
},
"dependencies": {
"axios": "^0.19.2",
"debounce": "^1.2.0",
"pnpm": "^6.14.5",
"rollup-plugin-replace": "^2.2.0",
"sirv-cli": "^1.0.1"
}
}

0
photothumb.db Normal file → Executable file
View File

1281
pnpm-lock.yaml Executable file

File diff suppressed because it is too large Load Diff

0
public/favicon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

0
public/global.css Normal file → Executable file
View File

2
public/index.html Normal file → Executable file
View File

@ -4,7 +4,7 @@
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Menuizer</title>
<title>Menus</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>

0
recipes.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

0
recipes.xcf Normal file → Executable file
View File

0
recipes_svelte.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

55
rollup.config.js Normal file → Executable file
View File

@ -1,30 +1,52 @@
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
import livereload from 'rollup-plugin-livereload';
import replace from 'rollup-plugin-replace';
import { terser } from 'rollup-plugin-terser';
import css from 'rollup-plugin-css-only';
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
'stdio': ['ignore', 'inherit', 'inherit'],
'shell': true
});
process.on('SIGTERM', toExit);
process.on('exit', toExit);
}
};
}
export default {
'input': 'src/main.js',
'output': {
'sourcemap': (!production),
'sourcemap': true,
'format': 'iife',
'name': 'app',
'file': 'public/build/bundle.js'
},
'plugins': [
svelte({
// enable run-time checks when not in production
'dev': !production,
// we'll extract any component CSS out into
// a separate file - better for performance
'css': css => {
css.write('public/build/bundle.css');
'compilerOptions': {
// enable run-time checks when not in production
'dev': !production
}
}),
// we'll extract any component CSS out into
// a separate file - better for performance
css({ 'output': 'bundle.css' }),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
@ -57,20 +79,3 @@ export default {
'clearScreen': false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
'stdio': ['ignore', 'inherit', 'inherit'],
'shell': true
});
}
}
};
}

76
rollup.config.js.old Executable file
View File

@ -0,0 +1,76 @@
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import replace from 'rollup-plugin-replace';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
'input': 'src/main.js',
'output': {
'sourcemap': (!production),
'format': 'iife',
'name': 'app',
'file': 'public/build/bundle.js'
},
'plugins': [
svelte({
// enable run-time checks when not in production
'dev': !production,
// we'll extract any component CSS out into
// a separate file - better for performance
'css': css => {
css.write('public/build/bundle.css');
}
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
'browser': true,
'dedupe': ['svelte']
}),
commonjs(),
replace({
'exclude': 'node_modules/**',
'ENV': JSON.stringify(production ? 'production' : 'development')
}),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
'watch': {
'clearScreen': false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
'stdio': ['ignore', 'inherit', 'inherit'],
'shell': true
});
}
}
};
}

0
src/App.svelte Normal file → Executable file
View File

8
src/components/Debug.svelte Normal file → Executable file
View File

@ -1,15 +1,15 @@
<script>
import {state} from '../store/store';
import {recipes, currentItem,filter} from '../store/store';
state.recipes.subscribe(async (v) => {
recipes.subscribe(async (v) => {
console.log('>> recipes', v);
});
state.currentItem.subscribe(async (v) => {
currentItem.subscribe(async (v) => {
console.log('>> currentItem', v);
});
state.filter.subscribe(async (v) => {
filter.subscribe(async (v) => {
console.log('>> filter', v);
});

164
src/components/Editor.svelte Normal file → Executable file
View File

@ -1,104 +1,112 @@
<script>
import { slide } from 'svelte/transition';
import { slide } from 'svelte/transition';
import { state } from '../store/store';
import debounce from 'debounce';
import { editMode, currentItem, state } from '../store/store';
import debounce from 'debounce';
let _editMode;
let _currentItem;
let meat;
let mealtype;
let _editMode;
let _currentItem;
let meat;
let mealtype;
let deleteEnabled = false;
let deleteEnabled = false;
$: {
meat = _currentItem.meat.toString();
mealtype = _currentItem.mealtype.toString();
}
$: {
// console.log('react', _currentItem);
/* meat = _currentItem.meat.toString();
mealtype = _currentItem.mealtype.toString();*/
}
$: deleteEnabled = (_currentItem.hash === '')
$: deleteEnabled = (_currentItem.hash === '');
state.editMode.subscribe(async (v) => {
_editMode = v;
});
editMode.subscribe(async (v) => {
_editMode = v;
state.currentItem.subscribe(async (v) => {
_currentItem = v;
});
if (_editMode) window.scrollTo(0, 0);
});
function deleteItem() {
currentItem.subscribe(async (v) => {
_currentItem = v;
_currentItem.mealtype = _currentItem.mealtype.toString();
_currentItem.meat = _currentItem.meat.toString();
});
function deleteItem() {
console.log('>> DELETE');
}
}
function closeEditor() {
state.closeEditor();
}
function closeEditor() {
state.closeEditor();
}
async function saveRecipe() {
await state.saveRecipe(_currentItem);
}
async function saveRecipe() {
await state.saveRecipe(_currentItem);
}
function pasteHandler(v) {
debouncedPasteProcessor(v);
}
function pasteHandler(v) {
debouncedPasteProcessor(v);
}
function pasteProcessor(item) {
const meats = [
'x',
'chicken',
'beef',
'pork',
'fish',
'egg',
'vegetable'
];
function pasteProcessor(item) {
const meats = [
'x',
'chicken',
'beef',
'pork',
'fish',
'egg',
'vegetable'
];
const newFragment = {};
const titleRegEx = /(?:#\s)(.*)(?:\n)/;
const linkRegEx = /(?:\[.*]\()(.*)(?:\))/;
const foodRegEx = /([vV]egetable|[pP]ork|[cC]hicken|[bB]eef|[fF]ish|[eE]gg)/g;
const mealTypeRegEx = /([sS]oup)/g;
const foodCount = {};
let winnerVal = 0;
let winnerId = 0;
const newFragment = {};
const titleRegEx = /(?:#\s)(.*)(?:\n)/;
const linkRegEx = /(?:\[.*]\()(.*)(?:\))/;
const foodRegEx = /([vV]egetable|[pP]ork|[cC]hicken|[bB]eef|[fF]ish|[eE]gg)/g;
const mealTypeRegEx = /([sS]oup)/g;
const foodCount = {};
let winnerVal = 0;
let winnerId = 0;
const newTitle = titleRegEx.exec(item.target.value);
const newLink = linkRegEx.exec(item.target.value);
const newTitle = titleRegEx.exec(item.target.value);
const newLink = linkRegEx.exec(item.target.value);
if (newTitle !== null) newFragment.name = newTitle[1];
if (newTitle !== null) newFragment.name = newTitle[1];
if (newLink !== null) newFragment.url = newLink[1];
if (newLink !== null) newFragment.url = newLink[1];
const matchedFoods = [...item.target.value.matchAll(foodRegEx)];
const mealTypes = [...item.target.value.matchAll(mealTypeRegEx)];
const matchedFoods = [...item.target.value.matchAll(foodRegEx)];
const mealTypes = [...item.target.value.matchAll(mealTypeRegEx)];
if (matchedFoods.length > 0) {
const deboxed = matchedFoods.map(fooditem => {
return fooditem[0].toLowerCase();
});
if (matchedFoods.length > 0) {
const deboxed = matchedFoods.map(fooditem => {
return fooditem[0].toLowerCase();
});
deboxed.forEach(el => {
foodCount[el] = foodCount[el] + 1 || 1;
});
deboxed.forEach(el => {
foodCount[el] = foodCount[el] + 1 || 1;
});
for (const key in foodCount)
if (foodCount[key] > winnerVal) {
winnerVal = foodCount[key];
winnerId = meats.indexOf(key);
}
newFragment.meat = winnerId;
for (const key in foodCount) {
if (foodCount[key] > winnerVal) {
winnerVal = foodCount[key];
winnerId = meats.indexOf(key);
}
}
if (mealTypes.length > 0)
newFragment.mealtype = 2;
else
newFragment.mealtype = 1;
_currentItem = {..._currentItem, ...newFragment};
newFragment.meat = winnerId.toString(10);
}
const debouncedPasteProcessor = debounce(pasteProcessor, 250);
if (mealTypes.length > 0) {
newFragment.mealtype = '2';
}
else {
newFragment.mealtype = '1';
}
_currentItem = { ..._currentItem, ...newFragment };
}
const debouncedPasteProcessor = debounce(pasteProcessor, 250);
</script>
@ -108,7 +116,7 @@
</style>
{#if _editMode}
<div class="container" transition:slide>
<div class="container" transition:slide>
<form autocomplete="off">
<label for="name">Name:</label>
<input type="text" name="name" id="name" bind:value={_currentItem.name} required/>
@ -120,7 +128,7 @@
<textarea id="md" name="md" cols="50" rows="10" bind:value={_currentItem.md} on:paste={pasteHandler}></textarea>
<label for="meat">Meat</label>
<select id="meat" name="meat" bind:value={meat} required>
<select id="meat" name="meat" bind:value={_currentItem.meat} required>
<option></option>
<option value="1">Chicken</option>
<option value="2">Beef</option>
@ -131,7 +139,7 @@
</select>
<label for="mealtype">Meal type</label>
<select id="mealtype" name="mealtype" bind:value={mealtype} required>
<select id="mealtype" name="mealtype" bind:value={_currentItem.mealtype} required>
<option></option>
<option value="1">Main</option>
<option value="2">Soup</option>

28
src/components/FilterBar.svelte Normal file → Executable file
View File

@ -1,5 +1,10 @@
<script>
import { state } from '../store/store';
import { onMount } from 'svelte';
let meatVal = '0';
let mealVal = '0';
const meals = ['', '1', '2', '128'];
function updateMeat(event) {
const newVal = event.target.value;
@ -11,6 +16,25 @@
state.updateMealFilter(newVal);
}
onMount(() => {
setTimeout(() => {
const mtVal = document.getElementById('meatVal').selectedIndex;
const mlVal = document.getElementById('mealVal').selectedIndex;
if (mtVal !== 0) {
meatVal = mtVal.toString(10);
state.updateMeatFilter(meatVal);
}
if (mlVal !== 0) {
mealVal = meals[mlVal];
state.updateMealFilter(mealVal);
}
}, 25);
});
</script>
@ -24,7 +48,7 @@
<div class="container">
<div class="filterBar grid-4">
<select on:change={updateMeat}>
<select id="meatVal" on:change={updateMeat} bind:value={meatVal}>
<option value="0">All</option>
<option value="1">Chicken</option>
<option value="2">Beef</option>
@ -34,7 +58,7 @@
<option value="6">Vegetable</option>
</select>
<select on:change={updateMeal}>
<select id="mealVal" on:change={updateMeal} bind:value={mealVal}>
<option value="0">All</option>
<option value="1">Mains</option>
<option value="2">Soups</option>

0
src/components/Header.svelte Normal file → Executable file
View File

0
src/components/RecipeItem.svelte Normal file → Executable file
View File

6
src/components/Recipes.svelte Normal file → Executable file
View File

@ -1,6 +1,6 @@
<script>
import { state } from '../store/store';
import { recipes, filter, state } from '../store/store';
import { onMount } from 'svelte';
import RecipeItem from './RecipeItem.svelte';
@ -12,12 +12,12 @@
'meal': '0'
};
state.recipes.subscribe(async (v) => {
recipes.subscribe(async (v) => {
_storedRecipes = v;
_recipes = doFilter(_storedRecipes);
});
state.filter.subscribe(async (v) => {
filter.subscribe(async (v) => {
_filter = v;
_recipes = doFilter(_storedRecipes);
});

10
src/main.js Normal file → Executable file
View File

@ -1,10 +1,10 @@
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
'target': document.body,
'props': {
}
});
export default app;
export default app;

42
src/store/store.js Normal file → Executable file
View File

@ -1,12 +1,13 @@
import { writable } from 'svelte/store';
import axios from 'axios';
const url = (ENV === 'production') ? 'https://menu.silvrtree.co.uk/recipes' : 'http://localhost:3000/recipes';
// const url = (ENV === 'production') ? 'https://menu.silvrtree.local/recipes' : 'http://localhost:3000/recipes';
const url = (ENV === 'production') ? 'http://menu.lan/recipes' : 'http://menu.silvrtree.local/recipes';
console.log('Env:', ENV);
console.log('Using:', url);
function Filter() {
const { subscribe, set, update } = writable({
const { subscribe, set, update } = writable({
'meat':'0',
'meal':'0'
});
@ -28,7 +29,7 @@ function Filter() {
function Recipes() {
const { subscribe, set, update } = writable([]);
return {
subscribe,
set,
@ -80,24 +81,25 @@ function CurrentItem() {
};
}
const editMode = EditMode();
const currentItem = CurrentItem();
const recipes = Recipes();
const filter = Filter();
const state = {
'editMode': EditMode(),
'currentItem': CurrentItem(),
'recipes': Recipes(),
'filter': Filter(),
newRecipe() {
console.log('>> Action:newRecipe');
this.editMode.newRecipe();
this.currentItem.clearItem();
editMode.newRecipe();
currentItem.clearItem();
},
async editRecipe(hash) {
const response = await axios.get(`${url}/${hash}`).catch((err) => {
console.error(err);
});
this.currentItem.updateItem(response.data);
this.editMode.newRecipe();
currentItem.updateItem(response.data);
editMode.newRecipe();
},
async saveRecipe(payload) {
console.log('>> Action:saveRecipe');
@ -125,21 +127,19 @@ const state = {
},
async fetchRecipes() {
const response = await axios.get(url);
this.recipes.set(response.data);
recipes.set(response.data);
},
closeEditor() {
this.editMode.closeEditor();
this.currentItem.clearItem();
editMode.closeEditor();
currentItem.clearItem();
},
updateMeatFilter(newVal) {
this.filter.updateMeat(newVal);
},
filter.updateMeat(newVal);
},
updateMealFilter(newVal) {
this.filter.updateMeal(newVal);
filter.updateMeal(newVal);
}
};
// export { currentItem, editMode, actions, state };
export { state };
export { currentItem, editMode, recipes, filter, state };