initial commit
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
vite.config.js.timestamp-*
|
||||
vite.config.ts.timestamp-*
|
||||
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2025 gogacoder <me@gogacoder.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
3384
package-lock.json
generated
Normal file
38
package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "nikita",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electric-sql/pglite": "^0.2.13",
|
||||
"@nikonell/splash": "latest",
|
||||
"@tauri-apps/api": "^2",
|
||||
"@tauri-apps/plugin-dialog": "^2.2.0",
|
||||
"@tauri-apps/plugin-fs": "^2.2.0",
|
||||
"@tauri-apps/plugin-shell": "^2",
|
||||
"drizzle-orm": "^0.36.3",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-static": "^3.0.5",
|
||||
"@sveltejs/kit": "^2.7.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
||||
"@tauri-apps/cli": "^2",
|
||||
"drizzle-kit": "^0.28.1",
|
||||
"sass": "^1.81.0",
|
||||
"svelte": "^5.0.0",
|
||||
"svelte-check": "^4.0.0",
|
||||
"tslib": "^2.8.0",
|
||||
"typescript": "^5.5.0",
|
||||
"vite": "^5.4.10"
|
||||
}
|
||||
}
|
||||
7
src-tauri/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Generated by Tauri
|
||||
# will have schema files for capabilities auto-completion
|
||||
/gen/schemas
|
||||
26
src-tauri/Cargo.toml
Normal file
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "nikita"
|
||||
version = "0.1.0"
|
||||
description = "App for CJSC Lesozavod No. 10 Belka business process management."
|
||||
authors = ["ber⁴"]
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
# The `_lib` suffix may seem redundant but it is necessary
|
||||
# to make the lib name unique and wouldn't conflict with the bin name.
|
||||
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
|
||||
name = "nikita_lib"
|
||||
crate-type = ["staticlib", "cdylib", "rlib"]
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tauri-plugin-shell = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tauri-plugin-fs = "2"
|
||||
tauri-plugin-dialog = "2"
|
||||
3
src-tauri/build.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
17
src-tauri/capabilities/default.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"$schema": "../gen/schemas/desktop-schema.json",
|
||||
"identifier": "default",
|
||||
"description": "Capability for the main window",
|
||||
"windows": [
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"core:default",
|
||||
"shell:allow-open",
|
||||
"fs:default",
|
||||
"fs:read-all",
|
||||
"fs:read-files",
|
||||
"fs:default",
|
||||
"dialog:default"
|
||||
]
|
||||
}
|
||||
BIN
src-tauri/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
src-tauri/icons/128x128@2x.png
Normal file
|
After Width: | Height: | Size: 6.8 KiB |
BIN
src-tauri/icons/32x32.png
Normal file
|
After Width: | Height: | Size: 974 B |
BIN
src-tauri/icons/Square107x107Logo.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src-tauri/icons/Square142x142Logo.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
src-tauri/icons/Square150x150Logo.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
src-tauri/icons/Square284x284Logo.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src-tauri/icons/Square30x30Logo.png
Normal file
|
After Width: | Height: | Size: 903 B |
BIN
src-tauri/icons/Square310x310Logo.png
Normal file
|
After Width: | Height: | Size: 8.4 KiB |
BIN
src-tauri/icons/Square44x44Logo.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src-tauri/icons/Square71x71Logo.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
src-tauri/icons/Square89x89Logo.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src-tauri/icons/StoreLogo.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
src-tauri/icons/icon.icns
Normal file
BIN
src-tauri/icons/icon.ico
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
src-tauri/icons/icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
16
src-tauri/src/lib.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
#[tauri::command]
|
||||
fn greet(name: &str) -> String {
|
||||
format!("Hello, {}! You've been greeted from Rust!", name)
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.invoke_handler(tauri::generate_handler![greet])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
6
src-tauri/src/main.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
fn main() {
|
||||
nikita_lib::run()
|
||||
}
|
||||
35
src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "nikita",
|
||||
"version": "0.1.0",
|
||||
"identifier": "com.nikita.app",
|
||||
"build": {
|
||||
"beforeDevCommand": "bun run dev",
|
||||
"devUrl": "http://localhost:1420",
|
||||
"beforeBuildCommand": "bun run build",
|
||||
"frontendDist": "../build"
|
||||
},
|
||||
"app": {
|
||||
"windows": [
|
||||
{
|
||||
"title": "nikita",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": null
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
13
src/app.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Tauri + SvelteKit + Typescript App</title>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
38
src/lib/entities/brigadeType.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { makeEntity } from "@nikonell/splash/entities/factory.js";
|
||||
import { FieldTypes } from "@nikonell/splash/types/entity.js";
|
||||
import { makeField } from "@nikonell/splash/entities/factory.js";
|
||||
|
||||
export interface BrigadeType {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const brigadeTypeFields = {
|
||||
name: makeField({
|
||||
name: "name",
|
||||
title: "Наименование",
|
||||
type: FieldTypes.String,
|
||||
required: true,
|
||||
placeholder: "Введите наименование",
|
||||
}),
|
||||
};
|
||||
|
||||
const brigadeTypeRelations = {};
|
||||
|
||||
export const brigadeType = makeEntity<
|
||||
BrigadeType,
|
||||
typeof brigadeTypeFields,
|
||||
typeof brigadeTypeRelations
|
||||
>({
|
||||
name: "brigade_type",
|
||||
title: "Вид бригады",
|
||||
extras: [],
|
||||
fields: brigadeTypeFields,
|
||||
relations: brigadeTypeRelations,
|
||||
defaultValues: [
|
||||
{ name: "Бригада по распиловке" },
|
||||
{ name: "Бригада по сушке" },
|
||||
{ name: "Бригада по обработке" },
|
||||
{ name: "Бригада пеллетного цеха" },
|
||||
],
|
||||
});
|
||||
13
src/lib/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { Section } from "@nikonell/splash/types/section.js";
|
||||
import { brigadeType } from "./entities/brigadeType";
|
||||
|
||||
export const entities = [brigadeType];
|
||||
|
||||
export const sections: Section[] = [
|
||||
{
|
||||
name: "commercial_service",
|
||||
title: "Коммерческая служба",
|
||||
entities: [brigadeType],
|
||||
extras: [],
|
||||
},
|
||||
];
|
||||
16
src/lib/utils/excel.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { readFile } from "./files"
|
||||
import * as XLSX from 'xlsx';
|
||||
|
||||
export const parseExcelFile = async (path: string): Promise<string[][] | null> => {
|
||||
try {
|
||||
const contents = await readFile(path);
|
||||
const workbook = XLSX.read(contents, { type: "array" });
|
||||
const wsNames = workbook.SheetNames;
|
||||
const sheet = workbook.Sheets[wsNames[0]];
|
||||
const rows = XLSX.utils.sheet_to_json<string[]>(sheet, { header: 1, raw: false, defval: "" });
|
||||
return rows
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
17
src/lib/utils/files.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { open } from '@tauri-apps/plugin-dialog';
|
||||
import { readFile as read, readTextFile as readText } from '@tauri-apps/plugin-fs';
|
||||
|
||||
export const requestSingleFile = async () => {
|
||||
return open({
|
||||
multiple: false,
|
||||
directory: false,
|
||||
});
|
||||
}
|
||||
|
||||
export const readFile = async (path: string): Promise<Uint8Array<ArrayBufferLike>> => {
|
||||
return read(path);
|
||||
}
|
||||
|
||||
export const readTextFile = async (path: string): Promise<string> => {
|
||||
return readText(path);
|
||||
}
|
||||
37
src/routes/+layout.svelte
Normal file
@@ -0,0 +1,37 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from "svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { page } from "$app/stores";
|
||||
import { initDatabase } from "@nikonell/splash/database/client.js";
|
||||
import {
|
||||
SkeletonPageLayout,
|
||||
SkeletonRowPage,
|
||||
} from "@nikonell/splash/components/pages";
|
||||
import { SkeletonTable } from "@nikonell/splash/components/ui";
|
||||
import { entities } from "../lib";
|
||||
|
||||
interface Props {
|
||||
children: Snippet;
|
||||
}
|
||||
|
||||
let { children }: Props = $props();
|
||||
|
||||
let loaded = $state(false);
|
||||
|
||||
onMount(async () => {
|
||||
await initDatabase(entities);
|
||||
loaded = true;
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if loaded}
|
||||
{@render children()}
|
||||
{:else}
|
||||
<SkeletonPageLayout>
|
||||
{#if $page.url.pathname === "/"}
|
||||
<SkeletonTable />
|
||||
{:else if ["/edit", "/create"].includes($page.url.pathname)}
|
||||
<SkeletonRowPage />
|
||||
{/if}
|
||||
</SkeletonPageLayout>
|
||||
{/if}
|
||||
5
src/routes/+layout.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// Tauri doesn't have a Node.js server to do proper SSR
|
||||
// so we will use adapter-static to prerender the app (SSG)
|
||||
// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info
|
||||
export const prerender = true;
|
||||
export const ssr = false;
|
||||
6
src/routes/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { entities, sections } from "$lib";
|
||||
import { DisplayTablePage } from "@nikonell/splash/components/pages";
|
||||
</script>
|
||||
|
||||
<DisplayTablePage {entities} {sections} />
|
||||
6
src/routes/create/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { entities, sections } from "$lib";
|
||||
import { CreateRowPage } from "@nikonell/splash/components/pages";
|
||||
</script>
|
||||
|
||||
<CreateRowPage {entities} {sections} />
|
||||
6
src/routes/edit/+page.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { entities, sections } from "$lib";
|
||||
import { EditRowPage } from "@nikonell/splash/components/pages";
|
||||
</script>
|
||||
|
||||
<EditRowPage {entities} {sections} />
|
||||
BIN
static/favicon.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
static/fonts/gilroy/Gilroy-Black.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Bold.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Extrabold.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Heavy.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Light.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Medium.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Regular.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Semibold.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-Thin.woff2
Normal file
BIN
static/fonts/gilroy/Gilroy-UltraLight.woff2
Normal file
15
svelte.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
// Tauri doesn't have a Node.js server to do proper SSR
|
||||
// so we will use adapter-static to prerender the app (SSG)
|
||||
// See: https://v2.tauri.app/start/frontend/sveltekit/ for more info
|
||||
import adapter from "@sveltejs/adapter-static";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
preprocess: vitePreprocess(),
|
||||
kit: {
|
||||
adapter: adapter(),
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
19
tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"moduleResolution": "bundler"
|
||||
}
|
||||
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
|
||||
// except $lib which is handled by https://kit.svelte.dev/docs/configuration#files
|
||||
//
|
||||
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||
}
|
||||
38
vite.config.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { defineConfig } from "vite";
|
||||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
|
||||
// @ts-expect-error process is a nodejs global
|
||||
const host = process.env.TAURI_DEV_HOST;
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(async () => ({
|
||||
plugins: [sveltekit()],
|
||||
optimizeDeps: {
|
||||
exclude: ['@electric-sql/pglite'],
|
||||
},
|
||||
|
||||
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
|
||||
//
|
||||
// 1. prevent vite from obscuring rust errors
|
||||
clearScreen: false,
|
||||
// 2. tauri expects a fixed port, fail if that port is not available
|
||||
server: {
|
||||
port: 1420,
|
||||
strictPort: true,
|
||||
host: host || false,
|
||||
hmr: host
|
||||
? {
|
||||
protocol: "ws",
|
||||
host,
|
||||
port: 1421,
|
||||
}
|
||||
: undefined,
|
||||
watch: {
|
||||
// 3. tell vite to ignore watching `src-tauri`
|
||||
ignored: ["**/src-tauri/**"],
|
||||
},
|
||||
fs: {
|
||||
allow: ['..']
|
||||
}
|
||||
},
|
||||
}));
|
||||