mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Minor format changes and fixes
This commit is contained in:
parent
40cb8b4ce8
commit
0bb902145c
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
@ -41,6 +41,7 @@
|
||||||
"Backquote",
|
"Backquote",
|
||||||
"BIGPR",
|
"BIGPR",
|
||||||
"cctext",
|
"cctext",
|
||||||
|
"Certbot",
|
||||||
"CIHT",
|
"CIHT",
|
||||||
"clsx",
|
"clsx",
|
||||||
"codemirror",
|
"codemirror",
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
"datv",
|
"datv",
|
||||||
"Debool",
|
"Debool",
|
||||||
"Decart",
|
"Decart",
|
||||||
|
"djangorestframework",
|
||||||
"Downvote",
|
"Downvote",
|
||||||
"EMPTYSET",
|
"EMPTYSET",
|
||||||
"exteor",
|
"exteor",
|
||||||
|
@ -72,6 +74,7 @@
|
||||||
"Litr",
|
"Litr",
|
||||||
"loct",
|
"loct",
|
||||||
"moprho",
|
"moprho",
|
||||||
|
"mypy",
|
||||||
"nomn",
|
"nomn",
|
||||||
"nooverlap",
|
"nooverlap",
|
||||||
"NPRO",
|
"NPRO",
|
||||||
|
@ -83,11 +86,13 @@
|
||||||
"PRTS",
|
"PRTS",
|
||||||
"pssv",
|
"pssv",
|
||||||
"pyconcept",
|
"pyconcept",
|
||||||
|
"pylint",
|
||||||
"pymorphy",
|
"pymorphy",
|
||||||
"Quantor",
|
"Quantor",
|
||||||
"razdel",
|
"razdel",
|
||||||
"reagraph",
|
"reagraph",
|
||||||
"Reindex",
|
"Reindex",
|
||||||
|
"rsconcept",
|
||||||
"rsedit",
|
"rsedit",
|
||||||
"rseditor",
|
"rseditor",
|
||||||
"rsform",
|
"rsform",
|
||||||
|
@ -98,6 +103,7 @@
|
||||||
"signup",
|
"signup",
|
||||||
"Slng",
|
"Slng",
|
||||||
"SMALLPR",
|
"SMALLPR",
|
||||||
|
"tailwindcss",
|
||||||
"tanstack",
|
"tanstack",
|
||||||
"toastify",
|
"toastify",
|
||||||
"tooltipic",
|
"tooltipic",
|
||||||
|
|
17
README.md
17
README.md
|
@ -1,13 +1,17 @@
|
||||||
# ConceptPortal
|
# ConceptPortal
|
||||||
|
|
||||||
React + Django based web portal for editing RSForm schemas.
|
React + Django based web portal for editing RSForm schemas.
|
||||||
This readme file is used mostly to document project dependencies
|
This readme file is used mostly to document project dependencies
|
||||||
|
|
||||||
# Contributing notes
|
# Contributing notes
|
||||||
|
|
||||||
!BEFORE PUSHING INTO MAIN!
|
!BEFORE PUSHING INTO MAIN!
|
||||||
|
|
||||||
- use Test config in VSCode to run tests before pushing commits / requests
|
- use Test config in VSCode to run tests before pushing commits / requests
|
||||||
- cd rsconcept/frontend & npm run build
|
- cd rsconcept/frontend & npm run build
|
||||||
|
|
||||||
# Frontend stack & Tooling [Vite + React + Typescript]
|
# Frontend stack & Tooling [Vite + React + Typescript]
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>npm install</summary>
|
<summary>npm install</summary>
|
||||||
<pre>
|
<pre>
|
||||||
|
@ -35,7 +39,9 @@ This readme file is used mostly to document project dependencies
|
||||||
<details>
|
<details>
|
||||||
<summary>npm install -D</summary>
|
<summary>npm install -D</summary>
|
||||||
<pre>
|
<pre>
|
||||||
- tailwindcss postcss autoprefixer
|
- tailwindcss
|
||||||
|
- postcss
|
||||||
|
- autoprefixer
|
||||||
- eslint-plugin-simple-import-sort
|
- eslint-plugin-simple-import-sort
|
||||||
- eslint-plugin-tsdoc
|
- eslint-plugin-tsdoc
|
||||||
- jest
|
- jest
|
||||||
|
@ -57,6 +63,7 @@ This readme file is used mostly to document project dependencies
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
# Backend stack & Tooling [Django + PostgreSQL/SQLite]
|
# Backend stack & Tooling [Django + PostgreSQL/SQLite]
|
||||||
|
|
||||||
- [ConceptCore](https://github.com/IRBorisov/ConceptCore)
|
- [ConceptCore](https://github.com/IRBorisov/ConceptCore)
|
||||||
<details>
|
<details>
|
||||||
<summary>requirements</summary>
|
<summary>requirements</summary>
|
||||||
|
@ -93,20 +100,24 @@ This readme file is used mostly to document project dependencies
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
# DevOps
|
# DevOps
|
||||||
|
|
||||||
- Docker compose
|
- Docker compose
|
||||||
- PowerShell
|
- PowerShell
|
||||||
- Certbot
|
- Certbot
|
||||||
- Docker VSCode extension
|
- Docker VSCode extension
|
||||||
|
|
||||||
# Developer Notes
|
# Developer Notes
|
||||||
|
|
||||||
## Local build (Windows 10+)
|
## Local build (Windows 10+)
|
||||||
|
|
||||||
- this is main developers build
|
- this is main developers build
|
||||||
- Install Python 3.9, NodeJS, VSCode, Docker Desktop
|
- Install Python 3.9, NodeJS, VSCode, Docker Desktop
|
||||||
- copy import wheels from ConceptCore to rsconcept/backend/import
|
- copy import wheels from ConceptCore to rsconcept/backend/import
|
||||||
- run rsconcept/backend/LocalEnvSetup.ps1
|
- run rsconcept/backend/LocalEnvSetup.ps1
|
||||||
- use VSCode configs in root folder to start developement
|
- use VSCode configs in root folder to start development
|
||||||
|
|
||||||
## Development build
|
## Development build
|
||||||
|
|
||||||
- this build does not use HTTPS and nginx for networking
|
- this build does not use HTTPS and nginx for networking
|
||||||
- backend and frontend debugging is supported
|
- backend and frontend debugging is supported
|
||||||
- hmr (hot updates) for frontend
|
- hmr (hot updates) for frontend
|
||||||
|
@ -114,11 +125,13 @@ This readme file is used mostly to document project dependencies
|
||||||
- populate initial data: 'scripts/dev/PopulateDevData.ps1'
|
- populate initial data: 'scripts/dev/PopulateDevData.ps1'
|
||||||
|
|
||||||
## Local production build
|
## Local production build
|
||||||
|
|
||||||
- this build is same as production except not using production secrets and working on localhost
|
- this build is same as production except not using production secrets and working on localhost
|
||||||
- provide TLS certificate (can be self-signed) 'nginx/cert/local-cert.pem' and 'nginx/cert/local-key.pem'
|
- provide TLS certificate (can be self-signed) 'nginx/cert/local-cert.pem' and 'nginx/cert/local-key.pem'
|
||||||
- run via 'docker compose -f "docker-compose-prod-local.yml" up --build -d'
|
- run via 'docker compose -f "docker-compose-prod-local.yml" up --build -d'
|
||||||
|
|
||||||
## Production build
|
## Production build
|
||||||
|
|
||||||
- provide secrets: 'secrets/db_password.txt' and 'django_key.txt'
|
- provide secrets: 'secrets/db_password.txt' and 'django_key.txt'
|
||||||
- setup domain names for application and API in configs: 'frontend\env\.env.production', 'rsconcept\backend\.env.dev', 'nginx\production.conf'
|
- setup domain names for application and API in configs: 'frontend\env\.env.production', 'rsconcept\backend\.env.dev', 'nginx\production.conf'
|
||||||
- provide privacy policy document in PDF: 'frontend/public/privacy.pdf'
|
- provide privacy policy document in PDF: 'frontend/public/privacy.pdf'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
@ -13,8 +13,7 @@
|
||||||
if (
|
if (
|
||||||
localStorage.getItem('darkMode') === 'true' ||
|
localStorage.getItem('darkMode') === 'true' ||
|
||||||
localStorage.getItem('color-theme') === 'dark' ||
|
localStorage.getItem('color-theme') === 'dark' ||
|
||||||
(!('color-theme' in localStorage) &&
|
(!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
||||||
) {
|
) {
|
||||||
document.documentElement.classList.add('dark');
|
document.documentElement.classList.add('dark');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,7 +2,7 @@ export default {
|
||||||
plugins: {
|
plugins: {
|
||||||
'postcss-import': {},
|
'postcss-import': {},
|
||||||
'tailwindcss/nesting': {},
|
'tailwindcss/nesting': {},
|
||||||
tailwindcss: {},
|
'tailwindcss': {},
|
||||||
autoprefixer: {},
|
'autoprefixer': {}
|
||||||
},
|
}
|
||||||
}
|
};
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
|
import { createBrowserRouter, Outlet, RouterProvider } from 'react-router-dom';
|
||||||
|
|
||||||
import ConceptToaster from './components/ConceptToaster';
|
import ConceptToaster from '@/components/ConceptToaster';
|
||||||
import Footer from './components/Footer';
|
import Footer from '@/components/Footer';
|
||||||
import Navigation from './components/Navigation';
|
import Navigation from '@/components/Navigation';
|
||||||
import { NavigationState } from './context/NavigationContext';
|
import { NavigationState } from '@/context/NavigationContext';
|
||||||
import { useConceptTheme } from './context/ThemeContext';
|
import { useConceptTheme } from '@/context/ThemeContext';
|
||||||
import CreateRSFormPage from './pages/CreateRSFormPage';
|
import CreateRSFormPage from '@/pages/CreateRSFormPage';
|
||||||
import HomePage from './pages/HomePage';
|
import HomePage from '@/pages/HomePage';
|
||||||
import LibraryPage from './pages/LibraryPage';
|
import LibraryPage from '@/pages/LibraryPage';
|
||||||
import LoginPage from './pages/LoginPage';
|
import LoginPage from '@/pages/LoginPage';
|
||||||
import ManualsPage from './pages/ManualsPage';
|
import ManualsPage from '@/pages/ManualsPage';
|
||||||
import NotFoundPage from './pages/NotFoundPage';
|
import NotFoundPage from '@/pages/NotFoundPage';
|
||||||
import RegisterPage from './pages/RegisterPage';
|
import RegisterPage from '@/pages/RegisterPage';
|
||||||
import RestorePasswordPage from './pages/RestorePasswordPage';
|
import RestorePasswordPage from '@/pages/RestorePasswordPage';
|
||||||
import RSFormPage from './pages/RSFormPage';
|
import RSFormPage from '@/pages/RSFormPage';
|
||||||
import UserProfilePage from './pages/UserProfilePage';
|
import UserProfilePage from '@/pages/UserProfilePage';
|
||||||
import { globalIDs } from './utils/constants';
|
import { globalIDs } from '@/utils/constants';
|
||||||
|
|
||||||
function Root() {
|
function Root() {
|
||||||
const { viewportHeight, mainHeight, showScroll } = useConceptTheme();
|
const { viewportHeight, mainHeight, showScroll } = useConceptTheme();
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
export default {
|
export default {
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
content: [
|
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||||
'./src/**/*.{js,jsx,ts,tsx}',
|
|
||||||
],
|
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {}
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: []
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,46 +1,38 @@
|
||||||
import react from '@vitejs/plugin-react';
|
import react from '@vitejs/plugin-react';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { defineConfig, loadEnv,PluginOption } from 'vite';
|
import { defineConfig, loadEnv, PluginOption } from 'vite';
|
||||||
|
|
||||||
import { dependencies } from './package.json';
|
import { dependencies } from './package.json';
|
||||||
|
|
||||||
// Packages to include in main app bundle
|
// Packages to include in main app bundle
|
||||||
const inlinePackages = ['react', 'react-router-dom', 'react-dom'];
|
const inlinePackages = ['react', 'react-router-dom', 'react-dom'];
|
||||||
|
|
||||||
// Roolup warnings that should not be displayed
|
// Rollup warnings that should not be displayed
|
||||||
const warningsToIgnore = [
|
const warningsToIgnore = [['SOURCEMAP_ERROR', "Can't resolve original location of error"]];
|
||||||
['SOURCEMAP_ERROR', "Can't resolve original location of error"]
|
|
||||||
];
|
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default (({ mode }: { mode: string }) => {
|
export default ({ mode }: { mode: string }) => {
|
||||||
process.env = {
|
process.env = {
|
||||||
...process.env,
|
...process.env,
|
||||||
...loadEnv(mode, process.cwd())
|
...loadEnv(mode, process.cwd())
|
||||||
};
|
};
|
||||||
const enableHttps = process.env.VITE_PORTAL_FRONT_HTTPS === 'true';
|
const enableHttps = process.env.VITE_PORTAL_FRONT_HTTPS === 'true';
|
||||||
return defineConfig({
|
return defineConfig({
|
||||||
plugins: [
|
appType: 'spa',
|
||||||
react(),
|
plugins: [react(), muteWarningsPlugin(warningsToIgnore)],
|
||||||
muteWarningsPlugin(warningsToIgnore),
|
|
||||||
],
|
|
||||||
server: {
|
server: {
|
||||||
port: Number(process.env.VITE_PORTAL_FRONT_PORT),
|
port: Number(process.env.VITE_PORTAL_FRONT_PORT),
|
||||||
|
https: enableHttps
|
||||||
// NOTE: https is not used for dev builds currently
|
|
||||||
https: enableHttps,
|
|
||||||
},
|
},
|
||||||
|
publicDir: 'public',
|
||||||
build: {
|
build: {
|
||||||
chunkSizeWarningLimit: 4000, // KB
|
chunkSizeWarningLimit: 4000, // KB
|
||||||
sourcemap: false,
|
sourcemap: false,
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
output: {
|
output: {
|
||||||
manualChunks: {
|
manualChunks: { ...renderChunks(dependencies) }
|
||||||
// Load chunks for dependencies separately
|
}
|
||||||
...renderChunks(dependencies),
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
|
@ -48,19 +40,17 @@ export default (({ mode }: { mode: string }) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
|
|
||||||
|
|
||||||
// ======== Internals =======
|
// ======== Internals =======
|
||||||
|
|
||||||
function renderChunks(deps: Record<string, string>) {
|
function renderChunks(deps: Record<string, string>) {
|
||||||
const chunks = {};
|
const chunks = {};
|
||||||
Object.keys(deps).forEach((key) => {
|
Object.keys(deps).forEach(key => {
|
||||||
if (inlinePackages.includes(key)) {
|
if (inlinePackages.includes(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
chunks[key] = [key];
|
chunks[key] = [key];
|
||||||
})
|
});
|
||||||
return chunks;
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,15 +59,14 @@ function muteWarningsPlugin(warningsToIgnore: string[][]): PluginOption {
|
||||||
return {
|
return {
|
||||||
name: 'mute-warnings',
|
name: 'mute-warnings',
|
||||||
enforce: 'pre',
|
enforce: 'pre',
|
||||||
config: (userConfig) => ({
|
config: userConfig => ({
|
||||||
build: {
|
build: {
|
||||||
rollupOptions: {
|
rollupOptions: {
|
||||||
onwarn(warning, defaultHandler) {
|
onwarn(warning, defaultHandler) {
|
||||||
if (warning.code) {
|
if (warning.code) {
|
||||||
const muted = warningsToIgnore.find(
|
const muted = warningsToIgnore.find(
|
||||||
([code, message]) =>
|
([code, message]) => code == warning.code && warning.message.includes(message)
|
||||||
code == warning.code && warning.message.includes(message),
|
);
|
||||||
)
|
|
||||||
|
|
||||||
if (muted) {
|
if (muted) {
|
||||||
mutedMessages.add(muted.join());
|
mutedMessages.add(muted.join());
|
||||||
|
@ -86,20 +75,20 @@ function muteWarningsPlugin(warningsToIgnore: string[][]): PluginOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userConfig.build?.rollupOptions?.onwarn) {
|
if (userConfig.build?.rollupOptions?.onwarn) {
|
||||||
userConfig.build.rollupOptions.onwarn(warning, defaultHandler)
|
userConfig.build.rollupOptions.onwarn(warning, defaultHandler);
|
||||||
} else {
|
} else {
|
||||||
defaultHandler(warning)
|
defaultHandler(warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
closeBundle() {
|
closeBundle() {
|
||||||
const diff = warningsToIgnore.filter((x) => !mutedMessages.has(x.join()));
|
const diff = warningsToIgnore.filter(x => !mutedMessages.has(x.join()));
|
||||||
if (diff.length > 0) {
|
if (diff.length > 0) {
|
||||||
this.warn('Some of your muted warnings never appeared during the build process:');
|
this.warn('Some of your muted warnings never appeared during the build process:');
|
||||||
diff.forEach((m) => this.warn(`- ${m.join(': ')}`));
|
diff.forEach(m => this.warn(`- ${m.join(': ')}`));
|
||||||
}
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user