diff --git a/package-lock.json b/package-lock.json index e037641..db6a6d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.0", "@sealcode/jdd-editor": "^0.2.1", - "@sealcode/sealgen": "^0.18.10", + "@sealcode/sealgen": "^0.19.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", "@sealcode/ts-predicates": "^0.6.2", @@ -44,7 +44,7 @@ "nyc": "^17.1.0", "object-path": "^0.11.8", "qs": "^6.12.0", - "sealious": "^0.21.10", + "sealious": "^0.21.20", "slug": "^9.1.0", "stimulus": "^3.2.2", "tempstream": "^0.4.6", @@ -1366,6 +1366,85 @@ "node": ">= 18" } }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/sealgen": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.10.tgz", + "integrity": "sha512-Q+Wkeq01TFHXPM+LoRMbe9fqakSqgJnJxmjsw9Jzhm3dKBchTfj8BvRd1XWERWZZizCWmzkshLNoVx0kjyZ7rA==", + "license": "ISC", + "dependencies": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.2", + "@sealcode/ts-predicates": "^0.4.3", + "chokidar": "^3.6.0", + "colord": "^2.9.3", + "deepmerge": "^4.3.1", + "esbuild": "^0.20.0", + "escape-goat": "^4.0.0", + "fonsta": "^1.1.1", + "google-fonts-helper": "^3.4.1", + "husky": "^9.1.7", + "is-what": "^4.1.16", + "js-convert-case": "^4.2.0", + "json5": "^2.2.3", + "locreq": "^3.0.0", + "md5": "^2.3.0", + "merge": "^2.1.1", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "recursive-readdir": "^2.2.3", + "tempfile": "^5.0.0", + "tempstream": "^0.4.6", + "tiny-glob": "^0.2.9", + "wcag-contrast": "^3.0.0", + "ws": "^8.16.0", + "yargs": "^17.6.2" + }, + "bin": { + "sealgen": "lib/cli.js" + }, + "peerDependencies": { + "koa": "^2.13.0", + "koa-responsive-image-router": "^0.2.24", + "sealious": "^0.21" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/sealgen/node_modules/@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@sealcode/crud-ui/node_modules/@sealcode/ts-predicates": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", + "integrity": "sha512-UNSEacu7Ye8q0N8AJCJy37oJvv3w2OXKGkUnP7xO5lOY9DQviDPRDQhVaZdJ3/xMzXLm4UE3389ihctrPaov/A==", + "license": "ISC" + }, + "node_modules/@sealcode/crud-ui/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/@sealcode/file-manager": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@sealcode/file-manager/-/file-manager-1.0.2.tgz", @@ -1435,34 +1514,11 @@ "node": ">= 18" } }, - "node_modules/@sealcode/jdd/node_modules/@sealcode/ts-predicates": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.5.3.tgz", - "integrity": "sha512-EZI7e8EY8gI1pw2bKdevjl+fBJbcSlpNkCZ8XoEOV3cHakPujiT6M4l775RDkfxJSbLX7jhOBkhgPNDfmCpZbg==" - }, - "node_modules/@sealcode/jdd/node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/@sealcode/sealcodemirror": { - "version": "5.70.0-beta5", - "resolved": "https://registry.npmjs.org/@sealcode/sealcodemirror/-/sealcodemirror-5.70.0-beta5.tgz", - "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" - }, - "node_modules/@sealcode/sealgen": { + "node_modules/@sealcode/jdd-editor/node_modules/@sealcode/sealgen": { "version": "0.18.10", "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.10.tgz", "integrity": "sha512-Q+Wkeq01TFHXPM+LoRMbe9fqakSqgJnJxmjsw9Jzhm3dKBchTfj8BvRd1XWERWZZizCWmzkshLNoVx0kjyZ7rA==", + "license": "ISC", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -1500,6 +1556,110 @@ "sealious": "^0.21" } }, + "node_modules/@sealcode/jdd-editor/node_modules/@sealcode/sealgen/node_modules/@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@sealcode/jdd-editor/node_modules/@sealcode/ts-predicates": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", + "integrity": "sha512-UNSEacu7Ye8q0N8AJCJy37oJvv3w2OXKGkUnP7xO5lOY9DQviDPRDQhVaZdJ3/xMzXLm4UE3389ihctrPaov/A==", + "license": "ISC" + }, + "node_modules/@sealcode/jdd-editor/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@sealcode/jdd/node_modules/@sealcode/ts-predicates": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.5.3.tgz", + "integrity": "sha512-EZI7e8EY8gI1pw2bKdevjl+fBJbcSlpNkCZ8XoEOV3cHakPujiT6M4l775RDkfxJSbLX7jhOBkhgPNDfmCpZbg==" + }, + "node_modules/@sealcode/jdd/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@sealcode/sealcodemirror": { + "version": "5.70.0-beta5", + "resolved": "https://registry.npmjs.org/@sealcode/sealcodemirror/-/sealcodemirror-5.70.0-beta5.tgz", + "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" + }, + "node_modules/@sealcode/sealgen": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.0.tgz", + "integrity": "sha512-fnHg/1b+w4E0G4VUSk+Qh+rsHneh1F9LSXZBnQW3fF1+WdSUWgeaVMqUPpN6CXNmze1k7dMWQIjdXAS/AYgpFA==", + "license": "ISC", + "dependencies": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.2", + "@sealcode/ts-predicates": "^0.4.3", + "chokidar": "^3.6.0", + "colord": "^2.9.3", + "deepmerge": "^4.3.1", + "esbuild": "^0.20.0", + "escape-goat": "^4.0.0", + "fonsta": "^1.1.1", + "google-fonts-helper": "^3.4.1", + "husky": "^9.1.7", + "is-what": "^4.1.16", + "js-convert-case": "^4.2.0", + "json5": "^2.2.3", + "locreq": "^3.0.0", + "md5": "^2.3.0", + "merge": "^2.1.1", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "recursive-readdir": "^2.2.3", + "tempfile": "^5.0.0", + "tempstream": "^0.4.6", + "tiny-glob": "^0.2.9", + "wcag-contrast": "^3.0.0", + "ws": "^8.16.0", + "yargs": "^17.6.2" + }, + "bin": { + "sealgen": "lib/cli.js" + }, + "peerDependencies": { + "koa": "^2.13.0", + "koa-responsive-image-router": "^0.2.24", + "sealious": "^0.21", + "stimulus": "^3.2.2" + } + }, "node_modules/@sealcode/sealgen/node_modules/@sealcode/ts-predicates": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", @@ -12066,9 +12226,9 @@ "peer": true }, "node_modules/sealious": { - "version": "0.21.10", - "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.10.tgz", - "integrity": "sha512-T154pqrpj9KWjFPoiTut1nCcgi45xTfQztCMJ6UIuUFU4uBA2y5bdO4BFpjGLukeA8vYJXJlcTao+fHDuCBx3Q==", + "version": "0.21.20", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.20.tgz", + "integrity": "sha512-O4ac6jHkL3tP8UcN/3ybmOHMSo17IRaAFt5/FDixw+6upcQw8QeXuQgf7DR8gKdmNbNCiWLjqGoksw6GeQFWgg==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.1", @@ -12124,6 +12284,9 @@ }, "engines": { "node": ">=21.0" + }, + "peerDependencies": { + "koa-responsive-image-router": "^0.2.37" } }, "node_modules/sealious/node_modules/@sealcode/ts-predicates": { @@ -15941,6 +16104,63 @@ "koa-compose": "^4.1.0", "path-to-regexp": "^6.3.0" } + }, + "@sealcode/sealgen": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.10.tgz", + "integrity": "sha512-Q+Wkeq01TFHXPM+LoRMbe9fqakSqgJnJxmjsw9Jzhm3dKBchTfj8BvRd1XWERWZZizCWmzkshLNoVx0kjyZ7rA==", + "requires": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.2", + "@sealcode/ts-predicates": "^0.4.3", + "chokidar": "^3.6.0", + "colord": "^2.9.3", + "deepmerge": "^4.3.1", + "esbuild": "^0.20.0", + "escape-goat": "^4.0.0", + "fonsta": "^1.1.1", + "google-fonts-helper": "^3.4.1", + "husky": "^9.1.7", + "is-what": "^4.1.16", + "js-convert-case": "^4.2.0", + "json5": "^2.2.3", + "locreq": "^3.0.0", + "md5": "^2.3.0", + "merge": "^2.1.1", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "recursive-readdir": "^2.2.3", + "tempfile": "^5.0.0", + "tempstream": "^0.4.6", + "tiny-glob": "^0.2.9", + "wcag-contrast": "^3.0.0", + "ws": "^8.16.0", + "yargs": "^17.6.2" + }, + "dependencies": { + "@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "requires": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + } + } + } + }, + "@sealcode/ts-predicates": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", + "integrity": "sha512-UNSEacu7Ye8q0N8AJCJy37oJvv3w2OXKGkUnP7xO5lOY9DQviDPRDQhVaZdJ3/xMzXLm4UE3389ihctrPaov/A==" + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==" } } }, @@ -16018,6 +16238,63 @@ "koa-compose": "^4.1.0", "path-to-regexp": "^6.3.0" } + }, + "@sealcode/sealgen": { + "version": "0.18.10", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.10.tgz", + "integrity": "sha512-Q+Wkeq01TFHXPM+LoRMbe9fqakSqgJnJxmjsw9Jzhm3dKBchTfj8BvRd1XWERWZZizCWmzkshLNoVx0kjyZ7rA==", + "requires": { + "@koa/router": "^12.0.1", + "@sealcode/file-manager": "^1.0.2", + "@sealcode/ts-predicates": "^0.4.3", + "chokidar": "^3.6.0", + "colord": "^2.9.3", + "deepmerge": "^4.3.1", + "esbuild": "^0.20.0", + "escape-goat": "^4.0.0", + "fonsta": "^1.1.1", + "google-fonts-helper": "^3.4.1", + "husky": "^9.1.7", + "is-what": "^4.1.16", + "js-convert-case": "^4.2.0", + "json5": "^2.2.3", + "locreq": "^3.0.0", + "md5": "^2.3.0", + "merge": "^2.1.1", + "prettier": "^2.7.1", + "prompts": "^2.4.2", + "recursive-readdir": "^2.2.3", + "tempfile": "^5.0.0", + "tempstream": "^0.4.6", + "tiny-glob": "^0.2.9", + "wcag-contrast": "^3.0.0", + "ws": "^8.16.0", + "yargs": "^17.6.2" + }, + "dependencies": { + "@koa/router": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-12.0.2.tgz", + "integrity": "sha512-sYcHglGKTxGF+hQ6x67xDfkE9o+NhVlRHBqq6gLywaMc6CojK/5vFZByphdonKinYlMLkEkacm+HEse9HzwgTA==", + "requires": { + "debug": "^4.3.4", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.3.0" + } + } + } + }, + "@sealcode/ts-predicates": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.4.3.tgz", + "integrity": "sha512-UNSEacu7Ye8q0N8AJCJy37oJvv3w2OXKGkUnP7xO5lOY9DQviDPRDQhVaZdJ3/xMzXLm4UE3389ihctrPaov/A==" + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==" } } }, @@ -16027,9 +16304,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "@sealcode/sealgen": { - "version": "0.18.10", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.18.10.tgz", - "integrity": "sha512-Q+Wkeq01TFHXPM+LoRMbe9fqakSqgJnJxmjsw9Jzhm3dKBchTfj8BvRd1XWERWZZizCWmzkshLNoVx0kjyZ7rA==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.0.tgz", + "integrity": "sha512-fnHg/1b+w4E0G4VUSk+Qh+rsHneh1F9LSXZBnQW3fF1+WdSUWgeaVMqUPpN6CXNmze1k7dMWQIjdXAS/AYgpFA==", "requires": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -23966,9 +24243,9 @@ } }, "sealious": { - "version": "0.21.10", - "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.10.tgz", - "integrity": "sha512-T154pqrpj9KWjFPoiTut1nCcgi45xTfQztCMJ6UIuUFU4uBA2y5bdO4BFpjGLukeA8vYJXJlcTao+fHDuCBx3Q==", + "version": "0.21.20", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.20.tgz", + "integrity": "sha512-O4ac6jHkL3tP8UcN/3ybmOHMSo17IRaAFt5/FDixw+6upcQw8QeXuQgf7DR8gKdmNbNCiWLjqGoksw6GeQFWgg==", "requires": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.1", diff --git a/package.json b/package.json index a218917..ea2d2d9 100644 --- a/package.json +++ b/package.json @@ -45,13 +45,18 @@ ], "controllerDirs": [ "node_modules/@sealcode/jdd-editor/src/controllers", - "node_modules/@sealcode/sortable/src/controllers" + "node_modules/@sealcode/sortable/src/controllers", + "node_modules/@sealcode/sealgen/src/controllers" ], "copyToPublic": [ { "from": "node_modules/@sealcode/jdd-editor/assets/icons", "to": "dist/jdd-page/icons" }, + { + "from": "node_modules/@sealcode/sealgen/assets", + "to": "dist/sealgen" + }, { "from": "node_modules/@sealcode/simplemde/dist/simplemde.min.css", "to": "dist/simplemde.min.css" @@ -85,7 +90,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.0", "@sealcode/jdd-editor": "^0.2.1", - "@sealcode/sealgen": "^0.18.10", + "@sealcode/sealgen": "^0.19.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", "@sealcode/ts-predicates": "^0.6.2", @@ -112,7 +117,7 @@ "nyc": "^17.1.0", "object-path": "^0.11.8", "qs": "^6.12.0", - "sealious": "^0.21.10", + "sealious": "^0.21.20", "slug": "^9.1.0", "stimulus": "^3.2.2", "tempstream": "^0.4.6", diff --git a/src/back/app.ts b/src/back/app.ts index bebfe36..80c9c16 100644 --- a/src/back/app.ts +++ b/src/back/app.ts @@ -16,7 +16,6 @@ import { MONGO_PORT, MONGO_USERNAME, PORT, - UPLOADS_FS_DIR, } from "./config.js"; import ADMIN_CREDENTIALS from "./default-admin-credentials.js"; import { TheFileManager } from "./file-manager.js"; @@ -53,7 +52,6 @@ declare module "@sealcode/sealgen" { export default class TheApp extends App { FileManager = TheFileManager; config = { - upload_path: UPLOADS_FS_DIR, datastore_mongo: { host: MONGO_HOST, port: MONGO_PORT, diff --git a/src/back/index.ts b/src/back/index.ts index 5f7bb43..992ad74 100644 --- a/src/back/index.ts +++ b/src/back/index.ts @@ -8,7 +8,13 @@ import TheApp from "./app.js"; import { PORT, SEALIOUS_KILLSWITCH_PORT, SEALIOUS_SANITY } from "./config.js"; import { mainRouter } from "./routes/index.js"; import { waitForMeilisearch } from "./services/meilisearch.js"; -export const the_app = new TheApp(); +import { TheFileManager } from "./file-manager.js"; +import { imageRouter } from "./image-router.js"; + +export const the_app = new TheApp({ + fileManager: TheFileManager, + imageRouter: imageRouter, +}); void (async function () { await kill(PORT); diff --git a/src/back/routes/admin/forms.admin-forms.css b/src/back/routes/admin/forms.admin-forms.css index 0132571..ced526b 100644 --- a/src/back/routes/admin/forms.admin-forms.css +++ b/src/back/routes/admin/forms.admin-forms.css @@ -4,13 +4,16 @@ padding: 10px; background-color: color-mix(in srgb, var(--color) 10%, white); color: color-mix(in srgb, var(--color) 31%, black); - animation: notification-pop 400ms; + animation: form-message 400ms; animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55); } body:not(*:has(.jdd-container)) .form-container { + container-type: inline-size; + label { font-weight: bold; + font-size: 16px; } .form-input .form-input label { @@ -20,16 +23,31 @@ body:not(*:has(.jdd-container)) .form-container { .form { display: grid; grid-template-columns: 1fr 1fr; + --column-count: 2; + + @container (max-width: 900px) { + grid-template-columns: 1fr; + --column-count: 1; + } + grid-auto-flow: dense; gap: 8px; max-width: 1224px; margin: 0 auto; .form-messages { - grid-column: span 2; + grid-column: span var(--column-count); position: sticky; top: 16px; z-index: 3; + display: flex; + flex-flow: column; + gap: 8px; + + .form-message { + display: inline-block; + align-self: center; + } } & > .form-input__wrapper { @@ -44,7 +62,7 @@ body:not(*:has(.jdd-container)) .form-container { } & > h2 { - grid-column: span 2; + grid-column: span var(--column-count); font-family: var(--font-sans-serif); color: var(--color-brand-text-fg); font-size: 36px; @@ -54,7 +72,7 @@ body:not(*:has(.jdd-container)) .form-container { input[type="submit"] { background-color: var(--color-brand-accent); color: white; - grid-column: span 2; + grid-column: span var(--column-count); border-radius: 10px; height: 40px; border: none; @@ -81,7 +99,10 @@ body:not(*:has(.jdd-container)) .form-container { .form-input__wrapper--text, .form-input__wrapper--type__date, + .form-input__wrapper--type__datetime-local, .form-input__wrapper--type__number, + .form-input__wrapper--enum, + .form-input--type-simple-input, .form-input__wrapper--type__password { display: flex; flex-flow: row nowrap; @@ -99,13 +120,25 @@ body:not(*:has(.jdd-container)) .form-container { var(--color-brand-accent) 50%, transparent ); - height: 33px; - padding: 08px; + box-sizing: border-box; + height: 50px; + padding: 8px; flex-grow: 1; background-color: hsl(13.8, 40%, 100%); } } + .form-input__wrapper--file:not(.form-input__wrapper--control-type__photo) { + grid-row: span 2; + display: grid; + grid-template-columns: min-content 1fr; + grid-template-rows: min-content min-content; + + & > label { + grid-row: 1/3; + } + } + .form-input--type-checkboxed-list, .form-input__wrapper--type--table { ul { @@ -142,7 +175,7 @@ body:not(*:has(.jdd-container)) .form-container { .form-input__wrapper--title, .form-input__wrapper--subtitle, .form-input:has(textarea) { - grid-column: span 2; + grid-column: span var(--column-count); } } } diff --git a/src/back/routes/admin/forms.css b/src/back/routes/admin/forms.css new file mode 100644 index 0000000..601166e --- /dev/null +++ b/src/back/routes/admin/forms.css @@ -0,0 +1,151 @@ +@keyframes form-message { + from { + opacity: 0; + transform: scale(0.5); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +.file-list-item { + display: flex; + flex-flow: row; + + form { + padding-left: 20px; + } +} + +.form-message { + --color: black; + border: 1px solid var(--color); + border-radius: 5px; + padding: 10px; + animation: form-message 200ms; + box-shadow: 3px 3px 0px 0px #00000038; +} + +.form-message--error { + --color: var(--color-basic-red); + + &::before { + content: "❌"; + margin-right: 8px; + } +} + +.form-message--success { + --color: var(--color-basic-green); + + &::before { + content: "✅"; + margin-right: 8px; + } +} + +.form__error { + color: var(--color-basic-red); +} + +.form-input--type-simple-input { + display: flex; + align-items: center; + gap: 8px; +} + +.form-input__wrapper--checkbox { + display: flex; + flex-flow: row nowrap; + align-items: center; + + & > input[type="checkbox"] { + width: 15px; + height: 15px; + + + label { + padding-left: 10px; + } + } +} + +.form-input__wrapper--multiple-files--photos { + ul { + list-style: none; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); + grid-gap: 10px; + margin-bottom: 20px; + + li { + background-color: white; + box-shadow: 1px 1px 6px 0px #00000038; + padding: 10px; + display: grid; + grid-template-columns: 1fr 20px; + grid-template-rows: 20px auto min-content; + grid-row-gap: 10px; + + a { + grid-row: 1/3; + grid-column: 1/3; + + picture, + img { + width: 100%; + height: 150px; + object-fit: contain; + } + } + + .filename { + grid-row: 3/4; + grid-column: 1/3; + } + + form { + grid-row: 1/2; + grid-column: 2/3; + position: relative; + z-index: 2; + } + } + } +} + +.form { + .file_preview__icon { + display: flex; + flex-flow: row; + align-items: center; + + a { + word-wrap: anywhere; + text-align: center; + color: var(--color-brand-text-accent2); + } + + picture { + display: grid; + grid-template-columns: 1fr; + grid-template-rows: 1.3fr 1fr 1fr; + + img { + grid-row: 1/4; + grid-column: 1/2; + } + + .file_preview__icon__extension { + text-transform: uppercase; + color: var(--color-brand-accent2); + font-weight: bold; + grid-row: 2/3; + grid-column: 1/2; + text-align: center; + margin: auto; + } + } + } +} diff --git a/src/back/routes/admin/pages/shared.ts b/src/back/routes/admin/pages/shared.ts index 0ef10bf..eac78cf 100644 --- a/src/back/routes/admin/pages/shared.ts +++ b/src/back/routes/admin/pages/shared.ts @@ -1,9 +1,6 @@ import { Controls, Fields } from "@sealcode/sealgen"; import { Pages } from "../../../collections/collections.js"; -import { imageRouter } from "../../../image-router.js"; -import { TheFileManager } from "../../../file-manager.js"; - export const PagesFormFields = { url: new Fields.CollectionField(Pages.fields.url.required, Pages.fields.url), domain: new Fields.CollectionField(Pages.fields.domain.required, Pages.fields.domain), @@ -16,7 +13,7 @@ export const PagesFormFields = { Pages.fields.description.required, Pages.fields.description ), - imageForMetadata: new Fields.File(false, TheFileManager), + imageForMetadata: new Fields.File(false), hideNavigation: new Fields.Boolean(Pages.fields.hideNavigation.required), }; @@ -26,7 +23,7 @@ export const PagesFormControls = [ new Controls.SimpleInput(PagesFormFields.title, { label: "title" }), new Controls.SimpleInput(PagesFormFields.heading, { label: "heading" }), new Controls.SimpleInput(PagesFormFields.description, { label: "description" }), - new Controls.Photo(PagesFormFields.imageForMetadata, imageRouter, { + new Controls.Image(PagesFormFields.imageForMetadata, { label: "imageForMetadata", }), new Controls.Checkbox(PagesFormFields.hideNavigation, { label: "hideNavigation" }), diff --git a/src/back/routes/admin/password.form.ts b/src/back/routes/admin/password.form.ts index aaa6dbd..0577761 100644 --- a/src/back/routes/admin/password.form.ts +++ b/src/back/routes/admin/password.form.ts @@ -9,7 +9,7 @@ import { AdminURL } from "../urls.js"; export const actionName = "ResetPassword"; const fields = { - password: new Fields.SimpleFormField(true), + password: new Fields.Password(true), }; export const ResetPasswordShape = fieldsToShape(fields); @@ -20,10 +20,7 @@ export default new (class ResetPasswordForm extends Form { controls = [ new Controls.HTML("decoration", /* HTML */ `

Change password

`), - new Controls.SimpleInput(fields.password, { - label: "Password:", - type: "password", - }), + fields.password.getControl(), ]; async onSubmit(ctx: Context) { diff --git a/src/back/routes/dev/simple-crud-test/index.page.ts b/src/back/routes/dev/simple-crud-test/index.page.ts deleted file mode 100644 index 1ef2e59..0000000 --- a/src/back/routes/dev/simple-crud-test/index.page.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { CRUD } from "@sealcode/crud-ui"; -import type { CollectionItem } from "sealious"; -import type { ListFilterRender } from "@sealcode/sealgen"; -import { Controls, DefaultListFilters, Fields } from "@sealcode/sealgen"; -import { NavbarLinks } from "src/back/collections/collections.js"; -import html from "src/back/html.js"; - -export const actionName = "NavbarLinksCRUD"; - -const edit_fields = { - label: new Fields.CollectionField( - NavbarLinks.fields.label.required, - NavbarLinks.fields.label - ), - href: new Fields.CollectionField( - NavbarLinks.fields.href.required, - NavbarLinks.fields.href - ), -}; - -const edit_controls = [ - new Controls.SimpleInput(edit_fields.label, { label: "label" }), - new Controls.SimpleInput(edit_fields.href, { label: "href" }), -]; - -// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -const fields_for_display = [ - { field: "label", label: "label" }, - { field: "href", label: "href" }, -] as { - field: keyof (typeof NavbarLinks)["fields"]; - label: string; - format?: ( - value: unknown, - item: CollectionItem - ) => string | Promise; -}[]; - -// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -const fields_for_filters = [ - { field: "label", ...DefaultListFilters["text"] }, - { field: "href", ...DefaultListFilters["text"] }, -] as { - field: keyof (typeof NavbarLinks)["fields"]; - render?: ListFilterRender; - prepareValue?: (filter_value: unknown) => unknown; // set this function to change what filter value is passed to Sealious -}[]; - -export default new CRUD({ - collection: NavbarLinks, - nice_collection_name: "NavbarLinks", - fields_for_display, - fields_for_filters, - html, - list_title: "NavbarLinks list", - edit_title: "Edit", - edit_button_text: "Edit", - delete_button_text: "Delete", - back_to_list_button_text: "← Back to NavbarLinks list", - edit_fields, - edit_controls, - form_value_to_sealious_value: {}, - sealious_value_to_form_value: {}, - post_edit: async () => {}, - post_create: async () => {}, -}); diff --git a/src/back/routes/login.form.ts b/src/back/routes/login.form.ts index 708bec6..f6fad9d 100644 --- a/src/back/routes/login.form.ts +++ b/src/back/routes/login.form.ts @@ -11,8 +11,8 @@ import { AdminURL } from "./urls.js"; export const actionName = "Login"; const fields = { - username: new Fields.SimpleFormField(true), - password: new Fields.SimpleFormField(true), + username: new Fields.Text(true), + password: new Fields.Text(true), }; export const LoginShape = fieldsToShape(fields); diff --git a/src/back/routes/signIn.form.ts b/src/back/routes/signIn.form.ts index a883f66..87fc26c 100644 --- a/src/back/routes/signIn.form.ts +++ b/src/back/routes/signIn.form.ts @@ -1,6 +1,5 @@ import type { Context } from "koa"; import { Form, Fields, Controls, fieldsToShape } from "@sealcode/sealgen"; -import type { FlatTemplatable } from "tempstream"; import { tempstream } from "tempstream"; import { Users } from "../collections/collections.js"; import html from "../html.js"; @@ -10,12 +9,13 @@ import type { FormReaction, } from "@sealcode/sealgen/@types/forms/form-types.js"; import type { PageErrorMessage } from "@sealcode/sealgen/@types/page/mountable-with-fields.js"; +import type { Readable } from "stream"; export const actionName = "SignIn"; const fields = { - username: new Fields.SimpleFormField(true), - password: new Fields.SimpleFormField(true), + username: new Fields.TextBasedSimpleField(true), + password: new Fields.TextBasedSimpleField(true), }; export const SignInShape = fieldsToShape(fields); @@ -36,7 +36,7 @@ export default new (class SignInForm extends Form { ctx: Context, data: Record ): Promise<{ valid: boolean; error: string }> { - const { parsed: username } = await this.fields.username.getValue(ctx, data); + const { parsed: username } = await this.fields.username.getParsedValue(ctx, data); const filter: object = typeof username === "string" ? { username } : {}; @@ -108,7 +108,7 @@ export default new (class SignInForm extends Form { return; } - async renderError(ctx: Context, error: PageErrorMessage): Promise { + async renderError(ctx: Context, error: PageErrorMessage): Promise { return html({ ctx, title: "SignIn", description: "", body: `${error.message}` }); } diff --git a/src/front/controllers.ts b/src/front/controllers.ts index 19c4083..687c92f 100644 --- a/src/front/controllers.ts +++ b/src/front/controllers.ts @@ -49,6 +49,9 @@ application.register("submit-on-input", SubmitOnInput); import { default as Toast } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/toast.stimulus.js"; application.register("toast", Toast); +import { default as TableAddButton } from "./../../node_modules/@sealcode/sealgen/src/controllers/table-add-button.stimulus.js"; +application.register("table-add-button", TableAddButton); + import { default as Sortable } from "./../../node_modules/@sealcode/sortable/src/controllers/sortable.stimulus.js"; application.register("sortable", Sortable); diff --git a/src/main.css b/src/main.css index b692f5f..75a0e91 100644 --- a/src/main.css +++ b/src/main.css @@ -39,15 +39,6 @@ nav { } } -.form-input__wrapper--control-type__photo { - display: flex; - flex-flow: row wrap; - - label { - width: 100%; - } -} - body.jdd-editor { margin: 0 !important; padding: 0 !important; diff --git a/tests/__screenshots/simple-crud.test.ts/test-1.png b/tests/__screenshots/simple-crud.test.ts/test-1.png deleted file mode 100644 index 7989b23..0000000 Binary files a/tests/__screenshots/simple-crud.test.ts/test-1.png and /dev/null differ diff --git a/tests/__screenshots/simple-crud.test.ts/test-2.png b/tests/__screenshots/simple-crud.test.ts/test-2.png deleted file mode 100644 index 96a4823..0000000 Binary files a/tests/__screenshots/simple-crud.test.ts/test-2.png and /dev/null differ diff --git a/tests/__screenshots/simple-crud.test.ts/test-3.png b/tests/__screenshots/simple-crud.test.ts/test-3.png deleted file mode 100644 index f4a6174..0000000 Binary files a/tests/__screenshots/simple-crud.test.ts/test-3.png and /dev/null differ diff --git a/tests/__screenshots/tekst.test.ts/Tekst-component-1.png b/tests/__screenshots/tekst.test.ts/Tekst-component-1.png deleted file mode 100644 index b078b09..0000000 Binary files a/tests/__screenshots/tekst.test.ts/Tekst-component-1.png and /dev/null differ diff --git a/tests/simple-crud.test.ts b/tests/simple-crud.test.ts deleted file mode 100644 index 3193f01..0000000 --- a/tests/simple-crud.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { test, expect } from "./backend-fixture"; - -test("test", async ({ page, backend }) => { - await page.goto(`${backend.url}/dev/simple-crud-test/`); - await expect(page).toHaveScreenshot(); - await page.getByRole("link", { name: "Create" }).click(); - await expect(page).toHaveScreenshot(); - await page.getByRole("textbox", { name: "label" }).click(); - await page.getByRole("textbox", { name: "label" }).fill("navbar from simple crud"); - await page.getByRole("textbox", { name: "label" }).press("Tab"); - await page.getByRole("textbox", { name: "href" }).fill("/"); - await page.getByRole("button", { name: "Wyślij" }).click(); - await page.getByRole("link", { name: "navbar from simple crud" }).click(); - await expect(page).toHaveScreenshot(); -}); diff --git a/tests/tekst.test.ts b/tests/tekst.test.ts deleted file mode 100644 index ea0d931..0000000 --- a/tests/tekst.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { test, expect } from "./backend-fixture.js"; -import { setTimeout as sleep } from "node:timers/promises"; - -test("Tekst component", async ({ page, backend, setMarkdownValue }) => { - await page.goto(`${backend.url}/components`); - await page.waitForFunction(() => typeof (window as any).CodeMirror !== "undefined"); - await sleep(5000); - await page.locator('select[name="component"]').selectOption("tekst"); - await page - .locator(`select[name="$[components][0][args][color]"]`) - .selectOption("accent"); - await setMarkdownValue(`$[components][0][args][content]`, "Hamster, a dentist"); - - await page.getByRole("button", { name: "Preview" }).click(); - await expect(page).toHaveScreenshot(); -});