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