add ability to assign process to factory
This commit is contained in:
parent
e149726b83
commit
838830d2e6
1
lab2/.vscode/settings.json
vendored
1
lab2/.vscode/settings.json
vendored
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
".\\src-tauri\\Cargo.toml",
|
|
||||||
".\\src-tauri\\Cargo.toml"
|
".\\src-tauri\\Cargo.toml"
|
||||||
]
|
]
|
||||||
}
|
}
|
8
lab2/src-tauri/Cargo.lock
generated
8
lab2/src-tauri/Cargo.lock
generated
@ -2410,9 +2410,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.51"
|
version = "1.0.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
|
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@ -2428,9 +2428,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.23"
|
version = "1.0.26"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{models::{Manager, Factory, ManagerData, FactoryData, Id, Process, ProcessData}, manager_repo, factory_repo, process_repo};
|
use crate::{models::{Manager, Factory, ManagerData, FactoryData, Id, Process, ProcessData}, manager_repo, factory_repo, process_repo};
|
||||||
use sqlx::{Pool, MySql};
|
use sqlx::{Pool, MySql};
|
||||||
use tauri::State;
|
use tauri::State;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
@ -47,6 +46,30 @@ pub async fn delete_factory(id: Id, db: State<'_, Database>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn list_factory_processess(id: Id, db: State<'_, Database>) -> Result<Vec<Id>> {
|
||||||
|
let mut tx = db.pool.begin().await?;
|
||||||
|
let processess = factory_repo::list_processess(&mut tx, id).await?;
|
||||||
|
tx.commit().await?;
|
||||||
|
Ok(processess)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn add_factory_process(factory_id: Id, process_id: Id, db: State<'_, Database>) -> Result<()> {
|
||||||
|
let mut tx = db.pool.begin().await?;
|
||||||
|
factory_repo::add_process(&mut tx, factory_id, process_id).await?;
|
||||||
|
tx.commit().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn delete_factory_process(factory_id: Id, process_id: Id, db: State<'_, Database>) -> Result<()> {
|
||||||
|
let mut tx = db.pool.begin().await?;
|
||||||
|
factory_repo::delete_process(&mut tx, factory_id, process_id).await?;
|
||||||
|
tx.commit().await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------- Manager ---------------------------
|
// --------------------- Manager ---------------------------
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::models::{Id, FactoryData, Factory};
|
use crate::models::{Id, FactoryData, Factory};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use sqlx::{Transaction, MySql};
|
use sqlx::{Transaction, MySql, Row};
|
||||||
|
|
||||||
type MySqlTransaction<'a> = Transaction<'a, MySql>;
|
type MySqlTransaction<'a> = Transaction<'a, MySql>;
|
||||||
|
|
||||||
@ -15,8 +15,18 @@ pub async fn create_table(tx: &mut MySqlTransaction<'_>) -> Result<()> {
|
|||||||
|
|
||||||
PRIMARY KEY(ID),
|
PRIMARY KEY(ID),
|
||||||
UNIQUE(FK_MANAGER_ID),
|
UNIQUE(FK_MANAGER_ID),
|
||||||
FOREIGN KEY(FK_MANAGER_ID) REFERENCES MANAGER (ID) ON DELETE CASCADE
|
FOREIGN KEY(FK_MANAGER_ID) REFERENCES MANAGER (ID)
|
||||||
);"#).execute(tx).await?;
|
);"#).execute(&mut *tx).await?;
|
||||||
|
sqlx::query(r#"
|
||||||
|
CREATE TABLE `factory_supports_processes` (
|
||||||
|
FK_PROCESS_ID bigint unsigned NOT NULL,
|
||||||
|
FK_FACTORY_ID bigint unsigned NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY(FK_PROCESS_ID, FK_FACTORY_ID),
|
||||||
|
FOREIGN KEY(FK_PROCESS_ID) REFERENCES PROCESS (ID),
|
||||||
|
FOREIGN KEY(FK_FACTORY_ID) REFERENCES FACTORY (ID)
|
||||||
|
);"#)
|
||||||
|
.execute(&mut *tx).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,8 +48,7 @@ pub async fn add(tx: &mut MySqlTransaction<'_>, manager_id: Id, factory: &Factor
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list(tx: &mut MySqlTransaction<'_>) -> Result<Vec<Factory>> {
|
pub async fn list(tx: &mut MySqlTransaction<'_>) -> Result<Vec<Factory>> {
|
||||||
let factories = sqlx::query_as::<_, Factory>(
|
let factories = sqlx::query_as::<_, Factory>(r#"
|
||||||
r#"
|
|
||||||
SELECT
|
SELECT
|
||||||
ID as id,
|
ID as id,
|
||||||
NAME as name,
|
NAME as name,
|
||||||
@ -57,6 +66,10 @@ pub async fn delete(tx: &mut MySqlTransaction<'_>, id: Id) -> Result<()> {
|
|||||||
.bind(id)
|
.bind(id)
|
||||||
.execute(&mut *tx).await?;
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
|
sqlx::query("DELETE FROM `factory_supports_processes` WHERE FK_FACTORY_ID = ?")
|
||||||
|
.bind(id)
|
||||||
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
sqlx::query("DELETE FROM `factory` WHERE ID = ?")
|
sqlx::query("DELETE FROM `factory` WHERE ID = ?")
|
||||||
.bind(id)
|
.bind(id)
|
||||||
.execute(&mut *tx).await?;
|
.execute(&mut *tx).await?;
|
||||||
@ -65,8 +78,7 @@ pub async fn delete(tx: &mut MySqlTransaction<'_>, id: Id) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(tx: &mut MySqlTransaction<'_>, id: Id, factory: &FactoryData) -> Result<()> {
|
pub async fn update(tx: &mut MySqlTransaction<'_>, id: Id, factory: &FactoryData) -> Result<()> {
|
||||||
sqlx::query(
|
sqlx::query(r#"
|
||||||
r#"
|
|
||||||
UPDATE `factory` SET
|
UPDATE `factory` SET
|
||||||
NAME = ?,
|
NAME = ?,
|
||||||
LOCATION = ?,
|
LOCATION = ?,
|
||||||
@ -80,4 +92,48 @@ pub async fn update(tx: &mut MySqlTransaction<'_>, id: Id, factory: &FactoryData
|
|||||||
.execute(tx).await?;
|
.execute(tx).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_process(tx: &mut MySqlTransaction<'_>, factory_id: Id, process_id: Id) -> Result<()> {
|
||||||
|
sqlx::query(r#"
|
||||||
|
INSERT INTO `factory_supports_processes`
|
||||||
|
(`FK_FACTORY_ID`, `FK_PROCESS_ID`)
|
||||||
|
VALUES
|
||||||
|
(?, ?)
|
||||||
|
"#)
|
||||||
|
.bind(factory_id)
|
||||||
|
.bind(process_id)
|
||||||
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn list_processess(tx: &mut MySqlTransaction<'_>, id: Id) -> Result<Vec<Id>> {
|
||||||
|
let processess = sqlx::query(r#"
|
||||||
|
SELECT
|
||||||
|
FK_PROCESS_ID
|
||||||
|
FROM `factory_supports_processes`
|
||||||
|
WHERE FK_FACTORY_ID = ?
|
||||||
|
"#)
|
||||||
|
.bind(id)
|
||||||
|
.fetch_all(tx).await?;
|
||||||
|
|
||||||
|
let processess = processess.into_iter()
|
||||||
|
.map(|r| r.get(0))
|
||||||
|
.collect();
|
||||||
|
Ok(processess)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_process(tx: &mut MySqlTransaction<'_>, factory_id: Id, process_id: Id) -> Result<()> {
|
||||||
|
sqlx::query(r#"
|
||||||
|
DELETE FROM `factory_supports_processes`
|
||||||
|
WHERE
|
||||||
|
FK_FACTORY_ID = ? AND
|
||||||
|
FK_PROCESS_ID = ?
|
||||||
|
"#)
|
||||||
|
.bind(factory_id)
|
||||||
|
.bind(process_id)
|
||||||
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
@ -11,16 +11,18 @@ use std::{env, process::exit};
|
|||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
|
||||||
use models::{ManagerData, FactoryData, ProcessData};
|
use models::{ManagerData, FactoryData, ProcessData};
|
||||||
use sqlx::{Pool, MySql, mysql::MySqlPoolOptions, Row};
|
use sqlx::{Pool, MySql, mysql::MySqlPoolOptions, Row, Transaction};
|
||||||
|
|
||||||
use api::*;
|
use api::*;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
type MySqlTransaction<'a> = Transaction<'a, MySql>;
|
||||||
|
|
||||||
async fn setup_tables(pool: &Pool<MySql>) -> Result<()> {
|
async fn setup_tables(pool: &Pool<MySql>) -> Result<()> {
|
||||||
let mut tx = pool.begin().await?;
|
let mut tx = pool.begin().await?;
|
||||||
manager_repo::create_table(&mut tx).await?;
|
manager_repo::create_table(&mut tx).await?;
|
||||||
factory_repo::create_table(&mut tx).await?;
|
|
||||||
process_repo::create_table(&mut tx).await?;
|
process_repo::create_table(&mut tx).await?;
|
||||||
|
factory_repo::create_table(&mut tx).await?;
|
||||||
tx.commit().await?;
|
tx.commit().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -37,13 +39,18 @@ async fn drop_all_tables(pool: &Pool<MySql>) -> Result<()> {
|
|||||||
|
|
||||||
async fn set_foreign_key_checks(pool: &Pool<MySql>, enable: bool) -> Result<()> {
|
async fn set_foreign_key_checks(pool: &Pool<MySql>, enable: bool) -> Result<()> {
|
||||||
let query = match enable {
|
let query = match enable {
|
||||||
true => "SET GLOBAL FOREIGN_KEY_CHECKS=1",
|
true => "SET FOREIGN_KEY_CHECKS=1",
|
||||||
false => "SET GLOBAL FOREIGN_KEY_CHECKS=0",
|
false => "SET FOREIGN_KEY_CHECKS=0",
|
||||||
};
|
};
|
||||||
sqlx::query(query).execute(pool).await?;
|
sqlx::query(query).execute(pool).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn add_test_process(tx: &mut MySqlTransaction<'_>, process: ProcessData) -> Result<()> {
|
||||||
|
process_repo::add(tx, &process).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_test_data(pool: &Pool<MySql>) -> Result<()> {
|
async fn add_test_data(pool: &Pool<MySql>) -> Result<()> {
|
||||||
let mut tx = pool.begin().await?;
|
let mut tx = pool.begin().await?;
|
||||||
let manager = ManagerData {
|
let manager = ManagerData {
|
||||||
@ -58,13 +65,23 @@ async fn add_test_data(pool: &Pool<MySql>) -> Result<()> {
|
|||||||
location: "idk".into(),
|
location: "idk".into(),
|
||||||
floor_size: 10.0,
|
floor_size: 10.0,
|
||||||
};
|
};
|
||||||
let process = ProcessData {
|
|
||||||
name: "Certifuge 9000".into(),
|
|
||||||
size: 10.0
|
|
||||||
};
|
|
||||||
let id = manager_repo::add(&mut tx, &manager).await?;
|
let id = manager_repo::add(&mut tx, &manager).await?;
|
||||||
factory_repo::add(&mut tx, id, &factory).await?;
|
factory_repo::add(&mut tx, id, &factory).await?;
|
||||||
process_repo::add(&mut tx, &process).await?;
|
|
||||||
|
add_test_process(&mut tx, ProcessData {
|
||||||
|
name: "Certifuge 9000".into(),
|
||||||
|
size: 10.0
|
||||||
|
}).await?;
|
||||||
|
|
||||||
|
add_test_process(&mut tx, ProcessData {
|
||||||
|
name: "Certifuge 9001".into(),
|
||||||
|
size: 20.0
|
||||||
|
}).await?;
|
||||||
|
|
||||||
|
add_test_process(&mut tx, ProcessData {
|
||||||
|
name: "Certifuge 9002".into(),
|
||||||
|
size: 30.0
|
||||||
|
}).await?;
|
||||||
|
|
||||||
tx.commit().await?;
|
tx.commit().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -103,6 +120,9 @@ async fn main() {
|
|||||||
list_factories,
|
list_factories,
|
||||||
delete_factory,
|
delete_factory,
|
||||||
update_factory,
|
update_factory,
|
||||||
|
list_factory_processess,
|
||||||
|
add_factory_process,
|
||||||
|
delete_factory_process,
|
||||||
|
|
||||||
list_managers,
|
list_managers,
|
||||||
update_manager,
|
update_manager,
|
||||||
|
@ -15,16 +15,6 @@ pub async fn create_table(tx: &mut MySqlTransaction<'_>) -> Result<()> {
|
|||||||
PRIMARY KEY(ID)
|
PRIMARY KEY(ID)
|
||||||
);"#)
|
);"#)
|
||||||
.execute(&mut *tx).await?;
|
.execute(&mut *tx).await?;
|
||||||
sqlx::query(r#"
|
|
||||||
CREATE TABLE `factory_supports_processes` (
|
|
||||||
FK_PROCESS_ID bigint unsigned NOT NULL,
|
|
||||||
FK_FACTORY_ID bigint unsigned NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY(FK_PROCESS_ID, FK_FACTORY_ID),
|
|
||||||
FOREIGN KEY(FK_PROCESS_ID) REFERENCES PROCESS (ID),
|
|
||||||
FOREIGN KEY(FK_FACTORY_ID) REFERENCES FACTORY (ID)
|
|
||||||
);"#)
|
|
||||||
.execute(&mut *tx).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -63,6 +53,10 @@ pub async fn delete(tx: &mut MySqlTransaction<'_>, id: Id) -> Result<()> {
|
|||||||
.bind(id)
|
.bind(id)
|
||||||
.execute(&mut *tx).await?;
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
|
sqlx::query("DELETE FROM `factory_supports_processes` WHERE FK_PROCESS_ID = ?")
|
||||||
|
.bind(id)
|
||||||
|
.execute(&mut *tx).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
import { Header, Content, SideNav, SideNavItems, SideNavLink } from "carbon-components-svelte";
|
import { Header, Content, SideNav, SideNavItems, SideNavLink } from "carbon-components-svelte";
|
||||||
import Home from './routes/Home.svelte'
|
import Home from './routes/Home.svelte'
|
||||||
import FactoriesManagers from './routes/Factories-Managers.svelte'
|
import FactoriesManagers from './routes/Factories-Managers.svelte'
|
||||||
import { factories, list_factories, list_managers, list_processess, managers, processess } from "./lib/api";
|
import { factories, factory_processess, list_factories, list_factory_processess, list_managers, list_processess, managers, processess } from "./lib/api";
|
||||||
import { onMount } from "svelte";
|
import { onMount } from "svelte";
|
||||||
import Processess from "./routes/Processess.svelte";
|
import Processess from "./routes/Processess.svelte";
|
||||||
import { Building, Calibrate } from "carbon-icons-svelte";
|
import { Building, Calibrate } from "carbon-icons-svelte";
|
||||||
@ -12,6 +12,9 @@
|
|||||||
$managers = await list_managers()
|
$managers = await list_managers()
|
||||||
$factories = await list_factories()
|
$factories = await list_factories()
|
||||||
$processess = await list_processess()
|
$processess = await list_processess()
|
||||||
|
for (var factory of $factories) {
|
||||||
|
$factory_processess[factory.id] = await list_factory_processess(factory.id)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let isSideNavOpen = false;
|
let isSideNavOpen = false;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Form, TextInput, NumberInput } from "carbon-components-svelte";
|
import { Form, TextInput, NumberInput, DataTable } from "carbon-components-svelte";
|
||||||
import type { FactoryData } from "./api"
|
import type { FactoryData } from "./api"
|
||||||
|
|
||||||
export let factory: FactoryData = {
|
export let factory: FactoryData = {
|
||||||
|
@ -61,30 +61,30 @@
|
|||||||
{rows}
|
{rows}
|
||||||
>
|
>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<ToolbarBatchActions
|
<ToolbarBatchActions
|
||||||
bind:active={activeDelete}
|
bind:active={activeDelete}
|
||||||
on:cancel={(e) => {
|
on:cancel={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
activeDelete = false;
|
activeDelete = false;
|
||||||
}}
|
}}
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon={TrashCan}
|
|
||||||
disabled={selectedRowIds.length === 0}
|
|
||||||
on:click={deleteSelectedRows}
|
|
||||||
>
|
>
|
||||||
Delete
|
<Button
|
||||||
</Button>
|
icon={TrashCan}
|
||||||
</ToolbarBatchActions>
|
disabled={selectedRowIds.length === 0}
|
||||||
<ToolbarContent>
|
on:click={deleteSelectedRows}
|
||||||
<ToolbarSearch
|
>
|
||||||
persistent
|
Delete
|
||||||
shouldFilterRows
|
</Button>
|
||||||
bind:filteredRowIds
|
</ToolbarBatchActions>
|
||||||
/>
|
<ToolbarContent>
|
||||||
<Button on:click={showAddModal}>Create</Button>
|
<ToolbarSearch
|
||||||
<Button on:click={() => activeDelete = true}>Delete</Button>
|
persistent
|
||||||
</ToolbarContent>
|
shouldFilterRows
|
||||||
|
bind:filteredRowIds
|
||||||
|
/>
|
||||||
|
<Button on:click={showAddModal}>Create</Button>
|
||||||
|
<Button on:click={() => activeDelete = true}>Delete</Button>
|
||||||
|
</ToolbarContent>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<svelte:fragment slot="cell" let:row let:cell>
|
<svelte:fragment slot="cell" let:row let:cell>
|
||||||
{#if cell.key === "update_btn"}
|
{#if cell.key === "update_btn"}
|
||||||
|
86
lab2/src/lib/ProcessList.svelte
Normal file
86
lab2/src/lib/ProcessList.svelte
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { Button, Dropdown } from "carbon-components-svelte"
|
||||||
|
import { AddAlt, TrashCan } from "carbon-icons-svelte"
|
||||||
|
import { processess as allProcessess, type Id } from "./api"
|
||||||
|
|
||||||
|
export let processess: Id[] = []
|
||||||
|
|
||||||
|
let allProcessItems = []
|
||||||
|
let selectedAdd = undefined
|
||||||
|
|
||||||
|
function getAvailableProcessess() {
|
||||||
|
return allProcessItems
|
||||||
|
.filter(item => !processess.includes(item.id))
|
||||||
|
.map(item => item.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
$: allProcessItems = $allProcessess.map(process => ({ id: process.id, text: process.name }))
|
||||||
|
|
||||||
|
$: {
|
||||||
|
let available = getAvailableProcessess()
|
||||||
|
if (!available.includes(selectedAdd) && available.length > 0) {
|
||||||
|
selectedAdd = available[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addRow(newId) {
|
||||||
|
processess = [ ...processess, newId ]
|
||||||
|
selectedAdd = getAvailableProcessess()[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function reset() {
|
||||||
|
selectedAdd = undefined
|
||||||
|
processess = []
|
||||||
|
}
|
||||||
|
|
||||||
|
export function prepare(newProcessess) {
|
||||||
|
processess = newProcessess
|
||||||
|
selectedAdd = getAvailableProcessess()[0]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-col gap-1rem">
|
||||||
|
{#each processess as id}
|
||||||
|
<div class="flex flex-row gap-1rem">
|
||||||
|
<Dropdown
|
||||||
|
class="flex-grow"
|
||||||
|
bind:selectedId={id}
|
||||||
|
items={allProcessItems.filter(item => item.id == id || !processess.includes(item.id))}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon={TrashCan}
|
||||||
|
iconDescription="Delete"
|
||||||
|
kind="danger-tertiary"
|
||||||
|
on:click={() => {
|
||||||
|
processess = processess.filter(row => row != id)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="flex flex-row gap-1rem">
|
||||||
|
{#if allProcessItems.length === processess.length}
|
||||||
|
<Dropdown
|
||||||
|
class="flex-grow"
|
||||||
|
selectedId={1}
|
||||||
|
items={[{ id: 1, text: "No process available" }]}
|
||||||
|
disabled={true}
|
||||||
|
/>
|
||||||
|
<Button icon={AddAlt} iconDescription="Add" disabled={true} />
|
||||||
|
{:else}
|
||||||
|
<Dropdown
|
||||||
|
class="flex-grow"
|
||||||
|
bind:selectedId={selectedAdd}
|
||||||
|
items={allProcessItems.filter(item => !processess.includes(item.id))}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon={AddAlt}
|
||||||
|
iconDescription="Add"
|
||||||
|
on:click={() => addRow(selectedAdd)}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,14 +1,8 @@
|
|||||||
import { invoke } from '@tauri-apps/api/tauri'
|
import { invoke } from '@tauri-apps/api/tauri'
|
||||||
import { writable } from 'svelte/store'
|
import { get, writable, type Writable } from 'svelte/store'
|
||||||
|
|
||||||
|
export type Id = number
|
||||||
|
|
||||||
export interface Manager {
|
|
||||||
id: number,
|
|
||||||
first_name: string,
|
|
||||||
surname: string,
|
|
||||||
phone_number?: string,
|
|
||||||
title: string,
|
|
||||||
email?: string
|
|
||||||
}
|
|
||||||
export interface ManagerData {
|
export interface ManagerData {
|
||||||
first_name: string,
|
first_name: string,
|
||||||
surname: string,
|
surname: string,
|
||||||
@ -16,42 +10,63 @@ export interface ManagerData {
|
|||||||
title: string,
|
title: string,
|
||||||
email?: string
|
email?: string
|
||||||
}
|
}
|
||||||
|
export interface Manager extends ManagerData {
|
||||||
export interface Factory {
|
id: Id
|
||||||
id: number,
|
|
||||||
name: string,
|
|
||||||
location: string,
|
|
||||||
floor_size: number,
|
|
||||||
manager_id: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FactoryData {
|
export interface FactoryData {
|
||||||
name: string,
|
name: string,
|
||||||
location: string,
|
location: string,
|
||||||
floor_size: number
|
floor_size: number
|
||||||
}
|
}
|
||||||
|
export interface Factory extends FactoryData {
|
||||||
export interface Process {
|
id: Id,
|
||||||
id: number,
|
manager_id: Id
|
||||||
name: string,
|
|
||||||
size: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ProcessData {
|
export interface ProcessData {
|
||||||
name: string,
|
name: string,
|
||||||
size: number
|
size: number
|
||||||
}
|
}
|
||||||
|
export interface Process extends ProcessData {
|
||||||
|
id: Id
|
||||||
|
}
|
||||||
|
|
||||||
export let factories = writable<Factory[]>([])
|
export let factory_processess = writable<Record<Id, Id[]>>([])
|
||||||
export let managers = writable<Manager[]>([])
|
export let factories = writable<Factory[]>([])
|
||||||
export let processess = writable<Process[]>([])
|
export let managers = writable<Manager[]>([])
|
||||||
|
export let processess = writable<Process[]>([])
|
||||||
|
|
||||||
|
function add_object<T>(objects: Writable<T[]>, object: T) {
|
||||||
|
objects.update((objects) => {
|
||||||
|
objects.push(object)
|
||||||
|
return objects
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_object<T>(objects: Writable<T[]>, index: number, updates: Partial<T>) {
|
||||||
|
if (index == -1) return
|
||||||
|
|
||||||
|
objects.update((objects) => {
|
||||||
|
const obj = objects[index]
|
||||||
|
for (var key in updates) {
|
||||||
|
obj[key] = updates[key]
|
||||||
|
}
|
||||||
|
return objects
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_object<T>(objects: Writable<T[]>, index: number) {
|
||||||
|
if (index == -1) return
|
||||||
|
|
||||||
|
objects.update((objects) => {
|
||||||
|
objects.splice(index, 1)
|
||||||
|
return objects
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function remove_manager_by_id(id: number) {
|
function remove_manager_by_id(id: number) {
|
||||||
managers.update(managers => {
|
remove_object(managers, get(managers).findIndex(m => m.id == id))
|
||||||
var index = managers.findIndex(m => m.id == id)
|
|
||||||
if (index != -1) {
|
|
||||||
managers.splice(index, 1)
|
|
||||||
}
|
|
||||||
return managers
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function list_factories(): Promise<Factory[]> {
|
export async function list_factories(): Promise<Factory[]> {
|
||||||
@ -66,82 +81,59 @@ export async function list_processess(): Promise<Process[]> {
|
|||||||
return invoke("list_processess")
|
return invoke("list_processess")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function list_factory_processess(id: number): Promise<Id[]> {
|
||||||
|
return invoke("list_factory_processess", { id })
|
||||||
|
}
|
||||||
|
|
||||||
// Result -> Promise<[factory_id, manager_id]>
|
// Result -> Promise<[factory_id, manager_id]>
|
||||||
export async function add_manager_factory(factory: FactoryData, manager: ManagerData): Promise<[number, number]> {
|
export async function add_manager_factory(factory: FactoryData, manager: ManagerData): Promise<[number, number]> {
|
||||||
// TODO: For now always assume success
|
// TODO: For now always assume success
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
let [factory_id, manager_id] = await invoke<[number, number]>("add_manager_factory", { factory, manager })
|
let [factory_id, manager_id] = await invoke<[number, number]>("add_manager_factory", { factory, manager })
|
||||||
|
|
||||||
factories.update((factories) => {
|
add_object<Factory>(factories, {
|
||||||
factories.push({
|
id: factory_id,
|
||||||
id: factory_id,
|
manager_id,
|
||||||
manager_id,
|
...factory
|
||||||
...factory
|
|
||||||
})
|
|
||||||
return factories
|
|
||||||
})
|
})
|
||||||
managers.update((managers) => {
|
add_object<Manager>(managers, {
|
||||||
managers.push({ id: manager_id, ...manager })
|
id: manager_id,
|
||||||
return managers
|
...manager
|
||||||
})
|
})
|
||||||
|
|
||||||
return [factory_id, manager_id]
|
return [factory_id, manager_id]
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update_manager(id: number, manager: ManagerData): Promise<void> {
|
export async function update_manager(id: number, manager: ManagerData): Promise<void> {
|
||||||
invoke("update_manager", { id, manager })
|
await invoke("update_manager", { id, manager })
|
||||||
|
|
||||||
managers.update((managers) => {
|
const index = get(managers).findIndex(f => f.id == id)
|
||||||
var index = managers.findIndex(f => f.id == id)
|
update_object(managers, index, manager)
|
||||||
if (index != -1) {
|
|
||||||
managers[index] = {
|
|
||||||
...managers[index],
|
|
||||||
...manager
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return managers
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update_factory(id: number, factory: FactoryData): Promise<void> {
|
export async function update_factory(id: number, factory: FactoryData): Promise<void> {
|
||||||
invoke("update_factory", { id, factory })
|
await invoke("update_factory", { id, factory })
|
||||||
|
|
||||||
factories.update((factories) => {
|
const index = get(factories).findIndex(f => f.id == id)
|
||||||
var index = factories.findIndex(f => f.id == id)
|
update_object(factories, index, factory)
|
||||||
if (index != -1) {
|
|
||||||
factories[index] = {
|
|
||||||
...factories[index],
|
|
||||||
...factory
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return factories
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function delete_factory(id: number): Promise<void> {
|
export async function delete_factory(id: number): Promise<void> {
|
||||||
invoke("delete_factory", { id })
|
await invoke("delete_factory", { id })
|
||||||
|
|
||||||
factories.update((factories) => {
|
const index = get(factories).findIndex(f => f.id == id)
|
||||||
var index = factories.findIndex(f => f.id == id)
|
if (index != -1) {
|
||||||
if (index != -1) {
|
var manager_id = factories[index]
|
||||||
remove_manager_by_id(factories[index].manager_id)
|
remove_object(factories, index)
|
||||||
factories.splice(index, 1)
|
remove_manager_by_id(manager_id)
|
||||||
}
|
}
|
||||||
return factories
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function delete_process(id: number): Promise<void> {
|
export async function delete_process(id: number): Promise<void> {
|
||||||
invoke("delete_process", { id })
|
await invoke("delete_process", { id })
|
||||||
|
|
||||||
processess.update((processess) => {
|
const index = get(processess).findIndex(f => f.id == id)
|
||||||
var index = processess.findIndex(f => f.id == id)
|
remove_object(processess, index)
|
||||||
if (index != -1) {
|
|
||||||
// TODO: Remove from associated factories
|
|
||||||
processess.splice(index, 1)
|
|
||||||
}
|
|
||||||
return processess
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function add_process(process: ProcessData): Promise<number> {
|
export async function add_process(process: ProcessData): Promise<number> {
|
||||||
@ -149,28 +141,63 @@ export async function add_process(process: ProcessData): Promise<number> {
|
|||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
let id = await invoke<number>("add_process", { process })
|
let id = await invoke<number>("add_process", { process })
|
||||||
|
|
||||||
processess.update((processess) => {
|
add_object<Process>(processess, {
|
||||||
processess.push({
|
id,
|
||||||
id,
|
...process
|
||||||
...process
|
|
||||||
})
|
|
||||||
return processess
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update_process(id: number, process: ProcessData): Promise<void> {
|
export async function update_process(id: number, process: ProcessData): Promise<void> {
|
||||||
invoke("update_process", { id, process })
|
await invoke("update_process", { id, process })
|
||||||
|
|
||||||
processess.update((processess) => {
|
var index = get(processess).findIndex(f => f.id == id)
|
||||||
var index = processess.findIndex(f => f.id == id)
|
update_object(processess, index, process)
|
||||||
if (index != -1) {
|
}
|
||||||
processess[index] = {
|
|
||||||
...processess[index],
|
export async function add_factory_processess(factory_id: Id, process_ids: Id[]): Promise<void> {
|
||||||
...process
|
for (var processId of process_ids) {
|
||||||
}
|
await invoke("add_factory_process", { factoryId: factory_id, processId })
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_processess.update((factory_processess) => {
|
||||||
|
if (factory_processess[factory_id] == undefined) {
|
||||||
|
factory_processess[factory_id] = []
|
||||||
}
|
}
|
||||||
return processess
|
for (var process_id of process_ids) {
|
||||||
|
factory_processess[factory_id].push(process_id)
|
||||||
|
}
|
||||||
|
return factory_processess
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function update_factory_processess(factory_id: Id, process_ids: Id[]): Promise<void> {
|
||||||
|
let current = get(factory_processess)[factory_id]
|
||||||
|
|
||||||
|
let added = process_ids.filter(id => !current.includes(id))
|
||||||
|
let removed = current.filter(id => !process_ids.includes(id))
|
||||||
|
|
||||||
|
for (var processId of added) {
|
||||||
|
await invoke("add_factory_process", { factoryId: factory_id, processId })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var processId of removed) {
|
||||||
|
await invoke("delete_factory_process", { factoryId: factory_id, processId })
|
||||||
|
}
|
||||||
|
|
||||||
|
factory_processess.update((factory_processess) => {
|
||||||
|
if (factory_processess[factory_id] == undefined) {
|
||||||
|
factory_processess[factory_id] = []
|
||||||
|
}
|
||||||
|
|
||||||
|
var processess = factory_processess[factory_id]
|
||||||
|
for (var process_id of added) {
|
||||||
|
processess.push(process_id)
|
||||||
|
}
|
||||||
|
for (var process_id of removed) {
|
||||||
|
processess.splice(processess.findIndex(id => id === process_id), 1)
|
||||||
|
}
|
||||||
|
return factory_processess
|
||||||
})
|
})
|
||||||
}
|
}
|
@ -1,18 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {
|
|
||||||
DataTable,
|
|
||||||
Toolbar,
|
|
||||||
ToolbarContent,
|
|
||||||
ToolbarBatchActions,
|
|
||||||
Button,
|
|
||||||
ToolbarSearch,
|
|
||||||
Modal,
|
|
||||||
} from "carbon-components-svelte"
|
|
||||||
import TrashCan from "carbon-icons-svelte/lib/TrashCan.svelte"
|
|
||||||
import Edit from "carbon-icons-svelte/lib/Edit.svelte"
|
|
||||||
import ManagerForm from "../lib/ManagerForm.svelte"
|
import ManagerForm from "../lib/ManagerForm.svelte"
|
||||||
import FactoryForm from "../lib/FactoryForm.svelte"
|
import FactoryForm from "../lib/FactoryForm.svelte"
|
||||||
import { add_manager_factory, delete_factory, update_factory, update_manager, factories, managers } from "../lib/api"
|
import { add_manager_factory, delete_factory, update_factory, update_manager, factories, managers, factory_processess, add_factory_processess, update_factory_processess } from "../lib/api"
|
||||||
|
import ProcessList from "../lib/ProcessList.svelte"
|
||||||
|
import MyDataTable from "../lib/MyDataTable.svelte"
|
||||||
|
|
||||||
var rows = []
|
var rows = []
|
||||||
|
|
||||||
@ -29,19 +20,13 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let isModalShown = false
|
let processess = []
|
||||||
|
let resetProcessList, prepareProcessess
|
||||||
let resetFactoryForm, validateFactoryForm, factoryData
|
let resetFactoryForm, validateFactoryForm, factoryData
|
||||||
let resetManagerForm, validateManagerForm, managerData
|
let resetManagerForm, validateManagerForm, managerData
|
||||||
|
|
||||||
let activeDelete = false
|
let showUpdateModal = event => {
|
||||||
let selectedRowIds = []
|
let factory_id = event.detail
|
||||||
let filteredRowIds = []
|
|
||||||
|
|
||||||
let currentlyEditingId = undefined
|
|
||||||
let showUpdateModal = factory_id => {
|
|
||||||
console.log(factory_id)
|
|
||||||
currentlyEditingId = factory_id
|
|
||||||
|
|
||||||
let factory = $factories.find(factory => factory.id == factory_id)
|
let factory = $factories.find(factory => factory.id == factory_id)
|
||||||
let manager = $managers.find(manager => manager.id == factory.manager_id)
|
let manager = $managers.find(manager => manager.id == factory.manager_id)
|
||||||
|
|
||||||
@ -54,113 +39,58 @@
|
|||||||
managerData.title = manager.title
|
managerData.title = manager.title
|
||||||
managerData.email = manager.email
|
managerData.email = manager.email
|
||||||
|
|
||||||
isModalShown = true
|
if ($factory_processess[factory_id]) {
|
||||||
|
prepareProcessess([ ...$factory_processess[factory_id] ])
|
||||||
|
} else {
|
||||||
|
prepareProcessess([])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let showCreateModal = () => {
|
let showAddModal = () => {
|
||||||
currentlyEditingId = undefined
|
|
||||||
resetFactoryForm()
|
resetFactoryForm()
|
||||||
resetManagerForm()
|
resetManagerForm()
|
||||||
isModalShown = true
|
resetProcessList()
|
||||||
}
|
}
|
||||||
|
|
||||||
let closeModal = () => {
|
let validateModal = () => {
|
||||||
isModalShown = false
|
let isFactoryValid = validateFactoryForm()
|
||||||
}
|
let isManagerValid = validateManagerForm()
|
||||||
|
return isFactoryValid && isManagerValid
|
||||||
let deleteSelectedRows = async () => {
|
|
||||||
for (var id of selectedRowIds) {
|
|
||||||
await delete_factory(id)
|
|
||||||
}
|
|
||||||
selectedRowIds = []
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DataTable
|
<MyDataTable
|
||||||
zebra
|
addModalTitle={"Create factory & manager"}
|
||||||
selectable={activeDelete}
|
updateModalTitle={"Edit factory & manager"}
|
||||||
batchSelection={activeDelete}
|
bind:rows
|
||||||
sortable
|
on:showAddModal={showAddModal}
|
||||||
bind:selectedRowIds
|
on:showUpdateModal={showUpdateModal}
|
||||||
|
on:validateModal={validateModal}
|
||||||
|
on:add={async () => {
|
||||||
|
let [factory_id, _] = await add_manager_factory(factoryData, managerData)
|
||||||
|
await add_factory_processess(factory_id, processess)
|
||||||
|
}}
|
||||||
|
on:update={async (event) => {
|
||||||
|
let factory_id = event.detail
|
||||||
|
let manager_id = $factories.find(factory => factory.id == factory_id).manager_id
|
||||||
|
await update_factory(factory_id, factoryData)
|
||||||
|
await update_manager(manager_id, managerData)
|
||||||
|
await update_factory_processess(factory_id, processess)
|
||||||
|
}}
|
||||||
|
on:delete={async (event) => {
|
||||||
|
let ids = event.detail
|
||||||
|
for (var id of ids) {
|
||||||
|
await delete_factory(id)
|
||||||
|
}
|
||||||
|
}}
|
||||||
headers={[
|
headers={[
|
||||||
{ key: "factory_name", value: "Factory" },
|
{ key: "factory_name", value: "Factory" },
|
||||||
{ key: "factory_location", value: "Location" },
|
{ key: "factory_location", value: "Location" },
|
||||||
{ key: "factory_floor_size", value: "Floor size" },
|
{ key: "factory_floor_size", value: "Floor size" },
|
||||||
{ key: "manager_fullname", value: "Manager" },
|
{ key: "manager_fullname", value: "Manager" }
|
||||||
{ key: "update_btn", empty: true, width: "5rem" },
|
|
||||||
]}
|
]}
|
||||||
{rows}
|
|
||||||
>
|
>
|
||||||
<Toolbar>
|
<div class="flex flex-row gap-1rem mb-1rem">
|
||||||
<ToolbarBatchActions
|
|
||||||
bind:active={activeDelete}
|
|
||||||
on:cancel={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
activeDelete = false;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
icon={TrashCan}
|
|
||||||
disabled={selectedRowIds.length === 0}
|
|
||||||
on:click={deleteSelectedRows}
|
|
||||||
>
|
|
||||||
Delete
|
|
||||||
</Button>
|
|
||||||
</ToolbarBatchActions>
|
|
||||||
<ToolbarContent>
|
|
||||||
<ToolbarSearch
|
|
||||||
persistent
|
|
||||||
shouldFilterRows
|
|
||||||
bind:filteredRowIds
|
|
||||||
/>
|
|
||||||
<Button on:click={showCreateModal}>Create</Button>
|
|
||||||
<Button on:click={() => activeDelete = true}>Delete</Button>
|
|
||||||
</ToolbarContent>
|
|
||||||
</Toolbar>
|
|
||||||
<svelte:fragment slot="cell" let:row let:cell>
|
|
||||||
{#if cell.key === "update_btn"}
|
|
||||||
<Button
|
|
||||||
kind="ghost"
|
|
||||||
size="field"
|
|
||||||
iconDescription={"Edit"}
|
|
||||||
icon={Edit}
|
|
||||||
on:click={() => showUpdateModal(row.id)}
|
|
||||||
/>
|
|
||||||
{:else}
|
|
||||||
{cell.value}
|
|
||||||
{/if}
|
|
||||||
</svelte:fragment>
|
|
||||||
</DataTable>
|
|
||||||
|
|
||||||
<Modal
|
|
||||||
bind:open={isModalShown}
|
|
||||||
modalHeading={currentlyEditingId != undefined ? "Edit factory & manager" : "Create factory & manager"}
|
|
||||||
primaryButtonText="Confirm"
|
|
||||||
secondaryButtonText="Cancel"
|
|
||||||
on:open
|
|
||||||
on:click:button--secondary={closeModal}
|
|
||||||
on:submit={async () => {
|
|
||||||
let isFactoryValid = validateFactoryForm()
|
|
||||||
let isManagerValid = validateManagerForm()
|
|
||||||
if (!(isFactoryValid && isManagerValid)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentlyEditingId != undefined) {
|
|
||||||
// TODO: Handle if factory is not found
|
|
||||||
let manager_id = $factories.find(factory => factory.id == currentlyEditingId).manager_id
|
|
||||||
|
|
||||||
await update_factory(currentlyEditingId, factoryData) // TODO: handle if failed
|
|
||||||
await update_manager(manager_id, managerData) // TODO: handle if failed
|
|
||||||
} else {
|
|
||||||
await add_manager_factory(factoryData, managerData) // TODO: handle error
|
|
||||||
}
|
|
||||||
|
|
||||||
closeModal()
|
|
||||||
return true
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div class="flex flex-row gap-1rem">
|
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<p>Factory</p>
|
<p>Factory</p>
|
||||||
<FactoryForm
|
<FactoryForm
|
||||||
@ -178,4 +108,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
|
||||||
|
<div class="mt-1rem">
|
||||||
|
<p class="mb-0.5rem">Processess</p>
|
||||||
|
<ProcessList
|
||||||
|
bind:processess
|
||||||
|
bind:prepare={prepareProcessess}
|
||||||
|
bind:reset={resetProcessList}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</MyDataTable>
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
}}
|
}}
|
||||||
headers={[
|
headers={[
|
||||||
{ key: "name", value: "Name" },
|
{ key: "name", value: "Name" },
|
||||||
{ key: "size", value: "Size" }
|
{ key: "size", value: "Size (m²)" }
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<ProcessForm
|
<ProcessForm
|
||||||
|
Loading…
Reference in New Issue
Block a user