Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
774291c1c9
|
@ -8,12 +8,14 @@ public static class CredentialsMethods
|
||||||
{
|
{
|
||||||
public static Session? Login(this Credentials credentials)
|
public static Session? Login(this Credentials credentials)
|
||||||
{
|
{
|
||||||
if (credentials.Username.IsNullOrEmpty() || credentials.Password.IsNullOrEmpty())
|
var (username, password) = credentials;
|
||||||
|
|
||||||
|
if (username.IsNullOrEmpty() || password.IsNullOrEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var user = Db.GetUserByEmail(credentials.Username);
|
var user = Db.GetUserByEmail(username);
|
||||||
|
|
||||||
if (user is null || !user.VerifyPassword(credentials.Password))
|
if (user is null || !user.VerifyPassword(password))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
var session = new Session(user);
|
var session = new Session(user);
|
||||||
|
|
|
@ -41,7 +41,9 @@ public static class FolderMethods
|
||||||
|
|
||||||
public static IEnumerable<Folder> DescendantFolders(this Folder parent)
|
public static IEnumerable<Folder> DescendantFolders(this Folder parent)
|
||||||
{
|
{
|
||||||
return parent.Traverse(ChildFolders);
|
return parent
|
||||||
|
.TraverseDepthFirstPreOrder(ChildFolders)
|
||||||
|
.Skip(1); // skip self
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean IsDescendantOf(this Folder folder, Folder ancestor)
|
public static Boolean IsDescendantOf(this Folder folder, Folder ancestor)
|
||||||
|
|
|
@ -73,7 +73,9 @@ public static class UserMethods
|
||||||
|
|
||||||
public static IEnumerable<User> DescendantUsers(this User parent)
|
public static IEnumerable<User> DescendantUsers(this User parent)
|
||||||
{
|
{
|
||||||
return parent.Traverse(ChildUsers);
|
return parent
|
||||||
|
.TraverseDepthFirstPreOrder(ChildUsers)
|
||||||
|
.Skip(1); // skip self
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean IsDescendantOf(this User user, User ancestor)
|
public static Boolean IsDescendantOf(this User user, User ancestor)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
using System.Reactive.Linq;
|
|
||||||
using InnovEnergy.App.Backend.Database;
|
using InnovEnergy.App.Backend.Database;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
|
|
||||||
|
@ -8,7 +7,6 @@ public static class Program
|
||||||
{
|
{
|
||||||
public static void Main(String[] args)
|
public static void Main(String[] args)
|
||||||
{
|
{
|
||||||
|
|
||||||
Db.CreateFakeRelations();
|
Db.CreateFakeRelations();
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
namespace InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
|
public static class TreeTraversal
|
||||||
|
{
|
||||||
|
// public static IEnumerable<T> TraverseDepthFirstPreOrder<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
||||||
|
// {
|
||||||
|
// var stack = new Stack<IEnumerator<T>>();
|
||||||
|
//
|
||||||
|
// var iterator = root.AsSingleEnumerator();
|
||||||
|
//
|
||||||
|
// while (true)
|
||||||
|
// {
|
||||||
|
// while (iterator.MoveNext())
|
||||||
|
// {
|
||||||
|
// yield return iterator.Current;
|
||||||
|
//
|
||||||
|
// iterator = getChildren(iterator.Current).GetEnumerator();
|
||||||
|
// stack.Push(iterator);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// iterator.Dispose();
|
||||||
|
// if (stack.Count == 0)
|
||||||
|
// yield break;
|
||||||
|
//
|
||||||
|
// iterator = stack.Pop();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static IEnumerable<T> TraverseDepthFirstPreOrder<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
||||||
|
{
|
||||||
|
return Traverse(root,
|
||||||
|
getChildren,
|
||||||
|
branchOpen: true,
|
||||||
|
branchClose: false,
|
||||||
|
leaf: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> TraverseDepthFirstPostOrder<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
||||||
|
{
|
||||||
|
return Traverse(root,
|
||||||
|
getChildren,
|
||||||
|
branchOpen: false,
|
||||||
|
branchClose: true,
|
||||||
|
leaf: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<T> TraverseLeaves<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
||||||
|
{
|
||||||
|
return Traverse(root,
|
||||||
|
getChildren,
|
||||||
|
branchOpen: false,
|
||||||
|
branchClose: true,
|
||||||
|
leaf: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static IEnumerable<T> Traverse<T>(T root,
|
||||||
|
Func<T, IEnumerable<T>> getChildren,
|
||||||
|
Boolean branchOpen,
|
||||||
|
Boolean branchClose,
|
||||||
|
Boolean leaf)
|
||||||
|
{
|
||||||
|
// the if-checks on the constant booleans are
|
||||||
|
// almost free because of modern branch predictors
|
||||||
|
|
||||||
|
var stack = new Stack<IEnumerator<T>>();
|
||||||
|
var it = root.AsSingleEnumerator();
|
||||||
|
it.MoveNext();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
//////// going down ////////
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var cit = getChildren(it.Current).GetEnumerator();
|
||||||
|
|
||||||
|
if (cit.MoveNext()) // node has children, must be a branch
|
||||||
|
{
|
||||||
|
if (branchOpen)
|
||||||
|
yield return it.Current;
|
||||||
|
|
||||||
|
stack.Push(it);
|
||||||
|
it = cit;
|
||||||
|
}
|
||||||
|
else // no children, hence a leaf
|
||||||
|
{
|
||||||
|
var node = it.Current;
|
||||||
|
|
||||||
|
if (leaf)
|
||||||
|
yield return node;
|
||||||
|
|
||||||
|
if (!it.MoveNext())
|
||||||
|
break; // no more siblings: goto parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////// going up ////////
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
it.Dispose();
|
||||||
|
if (stack.Count == 0) yield break; // we got to the bottom of the stack, were done
|
||||||
|
|
||||||
|
it = stack.Pop();
|
||||||
|
|
||||||
|
var node = it.Current;
|
||||||
|
|
||||||
|
if (branchClose)
|
||||||
|
yield return node; // we've seen all its children: close the branch
|
||||||
|
|
||||||
|
if (it.MoveNext())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static IEnumerable<T> TraverseBreadthFirst<T>(this T node, Func<T, IEnumerable<T>> getChildren)
|
||||||
|
{
|
||||||
|
var queue = new Queue<IEnumerator<T>>();
|
||||||
|
|
||||||
|
var iterator = node.AsSingleEnumerator();
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
while (iterator.MoveNext())
|
||||||
|
{
|
||||||
|
yield return iterator.Current;
|
||||||
|
|
||||||
|
iterator.Current
|
||||||
|
.Apply(getChildren)
|
||||||
|
.GetEnumerator()
|
||||||
|
.Apply(queue.Enqueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator.Dispose();
|
||||||
|
|
||||||
|
if (queue.Count == 0)
|
||||||
|
yield break;
|
||||||
|
|
||||||
|
iterator = queue.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using static System.Runtime.CompilerServices.MethodImplOptions;
|
using static System.Runtime.CompilerServices.MethodImplOptions;
|
||||||
|
|
||||||
|
@ -6,6 +7,7 @@ namespace InnovEnergy.Lib.Utils;
|
||||||
|
|
||||||
public static class Utils
|
public static class Utils
|
||||||
{
|
{
|
||||||
|
public static Boolean IsNull<T>([NotNullWhen(returnValue: false)] this T t) => t is null;
|
||||||
|
|
||||||
public static IEnumerable<String> GetEnumStrings<T>(this T e) where T : Enum
|
public static IEnumerable<String> GetEnumStrings<T>(this T e) where T : Enum
|
||||||
{
|
{
|
||||||
|
@ -20,7 +22,7 @@ public static class Utils
|
||||||
[DebuggerStepThrough][MethodImpl(AggressiveInlining)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining)]
|
||||||
public static T ConvertTo<T>(this IConvertible c) where T : IConvertible
|
public static T ConvertTo<T>(this IConvertible c) where T : IConvertible
|
||||||
{
|
{
|
||||||
var t = typeof (T);
|
var t = typeof(T);
|
||||||
|
|
||||||
var type = t.IsEnum
|
var type = t.IsEnum
|
||||||
? Enum.GetUnderlyingType(t)
|
? Enum.GetUnderlyingType(t)
|
||||||
|
@ -50,13 +52,13 @@ public static class Utils
|
||||||
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
|
public static R Apply<T, R>(this T t, Func<T, R> f) => f(t);
|
||||||
|
|
||||||
[DebuggerStepThrough]
|
|
||||||
[MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R Apply<T1, T2, R>(this (T1 p1, T2 p2) t, Func<T1, T2, R> f) => f(t.p1, t.p2);
|
public static R Apply<T1, T2, R>(this (T1 p1, T2 p2) t, Func<T1, T2, R> f) => f(t.p1, t.p2);
|
||||||
|
|
||||||
[DebuggerStepThrough]
|
|
||||||
[MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R Apply<T1, T2, T3, R>(this (T1 p1, T2 p2, T3 p3) t, Func<T1, T2, T3, R> f) => f(t.p1, t.p2, t.p3);
|
public static R Apply<T1, T2, T3, R>(this (T1 p1, T2 p2, T3 p3) t, Func<T1, T2, T3, R> f) => f(t.p1, t.p2, t.p3);
|
||||||
|
|
||||||
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
[DebuggerStepThrough][MethodImpl(AggressiveInlining | AggressiveOptimization)]
|
||||||
public static R ApplyOrDefault<T, R>(this T t, Func<T, R> f, R @default)
|
public static R ApplyOrDefault<T, R>(this T t, Func<T, R> f, R @default)
|
||||||
|
@ -79,7 +81,7 @@ public static class Utils
|
||||||
? res
|
? res
|
||||||
: res + length;
|
: res + length;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Decimal Modulo(this Decimal dividend, Decimal divisor)
|
public static Decimal Modulo(this Decimal dividend, Decimal divisor)
|
||||||
{
|
{
|
||||||
var res = dividend % divisor;
|
var res = dividend % divisor;
|
||||||
|
@ -89,111 +91,39 @@ public static class Utils
|
||||||
: res + divisor;
|
: res + divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<T> Traverse<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
|
||||||
{
|
|
||||||
var stack = new Stack<IEnumerator<T>>();
|
|
||||||
var it = root.AsSingleEnumerator();
|
|
||||||
it.MoveNext();
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
//////// going down ////////
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var cit = getChildren(it.Current).GetEnumerator();
|
|
||||||
|
|
||||||
if (cit.MoveNext()) // node has children, must be a branch
|
|
||||||
{
|
|
||||||
yield return it.Current;
|
|
||||||
|
|
||||||
stack.Push(it);
|
|
||||||
it = cit;
|
|
||||||
}
|
|
||||||
else // no children, hence a leaf
|
|
||||||
{
|
|
||||||
var node = it.Current;
|
|
||||||
|
|
||||||
yield return node;
|
|
||||||
|
|
||||||
if (!it.MoveNext())
|
|
||||||
break; // no more siblings: goto parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////// going up ////////
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
it.Dispose();
|
|
||||||
if (stack.Count == 0)
|
|
||||||
yield break; // we got to the bottom of the stack, were done
|
|
||||||
|
|
||||||
it = stack.Pop();
|
|
||||||
|
|
||||||
if (it.MoveNext())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Int32 Clamp(this Int32 value, Int32 minValue, Int32 maxValue)
|
public static Int32 Clamp(this Int32 value, Int32 minValue, Int32 maxValue)
|
||||||
{
|
{
|
||||||
var clamped = Math.Min(maxValue, value);
|
var clamped = Math.Min(maxValue, value);
|
||||||
clamped = Math.Max(minValue, clamped);
|
clamped = Math.Max(minValue, clamped);
|
||||||
|
|
||||||
return clamped;
|
return clamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Double Clamp(this Double value, Double minValue, Double maxValue)
|
public static Double Clamp(this Double value, Double minValue, Double maxValue)
|
||||||
{
|
{
|
||||||
var clamped = Math.Min(maxValue, value);
|
var clamped = Math.Min(maxValue, value);
|
||||||
clamped = Math.Max(minValue, clamped);
|
clamped = Math.Max(minValue, clamped);
|
||||||
|
|
||||||
return clamped;
|
return clamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Decimal Clamp(this Decimal value, Decimal minValue, Decimal maxValue)
|
public static Decimal Clamp(this Decimal value, Decimal minValue, Decimal maxValue)
|
||||||
{
|
{
|
||||||
var clamped = Math.Min(maxValue, value);
|
var clamped = Math.Min(maxValue, value);
|
||||||
clamped = Math.Max(minValue, clamped);
|
clamped = Math.Max(minValue, clamped);
|
||||||
|
|
||||||
return clamped;
|
return clamped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static R ValueOrDefault<T, R>(this Dictionary<T, R> dict, T key, R defaultValue) where T : notnull
|
||||||
#pragma warning disable 8714
|
|
||||||
|
|
||||||
public static async Task<R> ApplyOrDefault<T, R>(this T t, Func<T, Task<R>> f, R @default)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await f(t);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return @default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static R ValueOrDefault<T, R>(this Dictionary<T, R> dict, T key, R defaultValue)
|
|
||||||
{
|
{
|
||||||
return dict.TryGetValue(key, out var value)
|
return dict.TryGetValue(key, out var value)
|
||||||
? value
|
? value
|
||||||
: defaultValue;
|
: defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Dictionary<K, V> CombineDicts<K,V>(params IEnumerable<KeyValuePair<K,V>>[] dicts)
|
|
||||||
{
|
|
||||||
return dicts.Flatten().ToDictionary(kv => kv.Key, kv => kv.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma warning restore 8714
|
|
||||||
|
|
||||||
|
|
||||||
public static void CopyFilesRecursively(String source, String target)
|
public static void CopyFilesRecursively(String source, String target)
|
||||||
{
|
{
|
||||||
CopyFilesRecursively(new DirectoryInfo(source), new DirectoryInfo(target));
|
CopyFilesRecursively(new DirectoryInfo(source), new DirectoryInfo(target));
|
||||||
|
@ -210,27 +140,4 @@ public static class Utils
|
||||||
|
|
||||||
|
|
||||||
public static String ExecutingProcessName => Process.GetCurrentProcess().ProcessName;
|
public static String ExecutingProcessName => Process.GetCurrentProcess().ProcessName;
|
||||||
|
|
||||||
public static IEnumerable<IEnumerable<T>> TraverseWithPath<T>(this T root, Func<T, IEnumerable<T>> getChildren)
|
|
||||||
{
|
|
||||||
var stack = new Stack<IEnumerator<T>>();
|
|
||||||
stack.Push(root.AsSingleEnumerator());
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
for (var top = stack.Peek(); top.MoveNext(); top = Push(top))
|
|
||||||
yield return stack.Select(p => p.Current);
|
|
||||||
|
|
||||||
var popped = stack.Pop();
|
|
||||||
popped.Dispose();
|
|
||||||
}
|
|
||||||
while (stack.Count > 0);
|
|
||||||
|
|
||||||
IEnumerator<T> Push(IEnumerator<T> node)
|
|
||||||
{
|
|
||||||
var top = getChildren(node.Current).GetEnumerator();
|
|
||||||
stack.Push(top);
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { NodeModel } from "@minoru/react-dnd-treeview";
|
||||||
import { createContext, ReactNode, useCallback, useState } from "react";
|
import { createContext, ReactNode, useCallback, useState } from "react";
|
||||||
import axiosConfig from "../../config/axiosConfig";
|
import axiosConfig from "../../config/axiosConfig";
|
||||||
import { I_Folder, I_Installation } from "../../util/types";
|
import { I_Folder, I_Installation } from "../../util/types";
|
||||||
|
@ -9,6 +10,8 @@ interface GroupContextProviderProps {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
setLoading: (value: boolean) => void;
|
setLoading: (value: boolean) => void;
|
||||||
getError: boolean;
|
getError: boolean;
|
||||||
|
tree: NodeModel<I_Folder | I_Installation>[];
|
||||||
|
setTree: (value: NodeModel<I_Folder | I_Installation>[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GroupContext = createContext<GroupContextProviderProps>({
|
export const GroupContext = createContext<GroupContextProviderProps>({
|
||||||
|
@ -18,19 +21,39 @@ export const GroupContext = createContext<GroupContextProviderProps>({
|
||||||
loading: false,
|
loading: false,
|
||||||
setLoading: () => {},
|
setLoading: () => {},
|
||||||
getError: false,
|
getError: false,
|
||||||
|
tree: [],
|
||||||
|
setTree: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getTreeData = (
|
||||||
|
data: (I_Folder | I_Installation)[]
|
||||||
|
): NodeModel<I_Folder | I_Installation>[] => {
|
||||||
|
return data.map((element) => {
|
||||||
|
const isFolder = element.type === "Folder";
|
||||||
|
return {
|
||||||
|
id: isFolder ? element.id : "installation-" + element.id,
|
||||||
|
parent: element.parentId,
|
||||||
|
text: element.name,
|
||||||
|
droppable: isFolder,
|
||||||
|
data: element,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const GroupContextProvider = ({ children }: { children: ReactNode }) => {
|
const GroupContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
const [data, setData] = useState<(I_Folder | I_Installation)[]>([]);
|
const [data, setData] = useState<(I_Folder | I_Installation)[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [getError, setGetError] = useState(false);
|
const [getError, setGetError] = useState(false);
|
||||||
|
const [tree, setTree] = useState<NodeModel<I_Folder | I_Installation>[]>([]);
|
||||||
|
|
||||||
const fetchData = useCallback(async () => {
|
const fetchData = useCallback(async () => {
|
||||||
|
console.log("fetchData");
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
return axiosConfig
|
return axiosConfig
|
||||||
.get("/GetAllFoldersAndInstallations")
|
.get("/GetAllFoldersAndInstallations")
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setData(res.data);
|
setData(res.data);
|
||||||
|
setTree(getTreeData(res.data));
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -41,7 +64,16 @@ const GroupContextProvider = ({ children }: { children: ReactNode }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GroupContext.Provider
|
<GroupContext.Provider
|
||||||
value={{ data, setData, fetchData, loading, setLoading, getError }}
|
value={{
|
||||||
|
data,
|
||||||
|
setData,
|
||||||
|
fetchData,
|
||||||
|
loading,
|
||||||
|
setLoading,
|
||||||
|
getError,
|
||||||
|
tree,
|
||||||
|
setTree,
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</GroupContext.Provider>
|
</GroupContext.Provider>
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
import { NodeModel } from "@minoru/react-dnd-treeview";
|
||||||
import { Button, CircularProgress, Grid } from "@mui/material";
|
import { Button, CircularProgress, Grid } from "@mui/material";
|
||||||
import { useFormik } from "formik";
|
import { useFormik } from "formik";
|
||||||
import { useContext, useState } from "react";
|
import { useContext, useState } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import axiosConfig from "../../config/axiosConfig";
|
import axiosConfig from "../../config/axiosConfig";
|
||||||
import { I_Folder } from "../../util/types";
|
import { I_Folder, I_Installation } from "../../util/types";
|
||||||
|
import { GroupContext } from "../Context/GroupContextProvider";
|
||||||
import InnovenergySnackbar from "../InnovenergySnackbar";
|
import InnovenergySnackbar from "../InnovenergySnackbar";
|
||||||
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
|
import InnovenergyTextfield from "../Layout/InnovenergyTextfield";
|
||||||
import { GroupContext } from "../Context/GroupContextProvider";
|
|
||||||
|
|
||||||
interface I_CustomerFormProps {
|
interface I_CustomerFormProps {
|
||||||
values: I_Folder;
|
values: I_Folder;
|
||||||
|
@ -16,9 +17,8 @@ interface I_CustomerFormProps {
|
||||||
const updateFolder = (data: I_Folder) => {
|
const updateFolder = (data: I_Folder) => {
|
||||||
return axiosConfig.put("/UpdateFolder", data);
|
return axiosConfig.put("/UpdateFolder", data);
|
||||||
};
|
};
|
||||||
const FolderForm = (props: I_CustomerFormProps) => {
|
|
||||||
const { fetchData } = useContext(GroupContext);
|
|
||||||
|
|
||||||
|
const FolderForm = (props: I_CustomerFormProps) => {
|
||||||
const { values, id } = props;
|
const { values, id } = props;
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
|
@ -26,6 +26,19 @@ const FolderForm = (props: I_CustomerFormProps) => {
|
||||||
const [error, setError] = useState();
|
const [error, setError] = useState();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const { setTree, tree } = useContext(GroupContext);
|
||||||
|
|
||||||
|
const updateTree = (newValues: I_Folder) => {
|
||||||
|
const elementToUpdate = tree.find(
|
||||||
|
(element) => element.data?.id.toString() === id
|
||||||
|
);
|
||||||
|
if (elementToUpdate) {
|
||||||
|
elementToUpdate.data = newValues;
|
||||||
|
elementToUpdate.text = newValues.name;
|
||||||
|
setTree([...tree]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const formik = useFormik({
|
const formik = useFormik({
|
||||||
initialValues: {
|
initialValues: {
|
||||||
name: values.name,
|
name: values.name,
|
||||||
|
@ -40,9 +53,9 @@ const FolderForm = (props: I_CustomerFormProps) => {
|
||||||
id: idAsNumber,
|
id: idAsNumber,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
|
updateTree({ ...values, ...formikValues, id: idAsNumber });
|
||||||
setSnackbarOpen(true);
|
setSnackbarOpen(true);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
fetchData();
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
setSnackbarOpen(true);
|
setSnackbarOpen(true);
|
||||||
|
|
|
@ -17,23 +17,8 @@ import DragPreview from "./DragPreview";
|
||||||
import InnovenergySnackbar from "../../InnovenergySnackbar";
|
import InnovenergySnackbar from "../../InnovenergySnackbar";
|
||||||
import { GroupContext } from "../../Context/GroupContextProvider";
|
import { GroupContext } from "../../Context/GroupContextProvider";
|
||||||
|
|
||||||
const getTreeData = (
|
|
||||||
data: (I_Folder | I_Installation)[]
|
|
||||||
): NodeModel<I_Folder | I_Installation>[] => {
|
|
||||||
return data.map((element) => {
|
|
||||||
const isFolder = element.type === "Folder";
|
|
||||||
return {
|
|
||||||
id: isFolder ? element.id : "installation-" + element.id,
|
|
||||||
parent: element.parentId,
|
|
||||||
text: element.name,
|
|
||||||
droppable: isFolder,
|
|
||||||
data: element,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const GroupTree = () => {
|
const GroupTree = () => {
|
||||||
const { data, fetchData, loading, setLoading, getError } =
|
const { data, fetchData, loading, setLoading, getError, setTree, tree } =
|
||||||
useContext(GroupContext);
|
useContext(GroupContext);
|
||||||
const [putError, setPutError] = useState(false);
|
const [putError, setPutError] = useState(false);
|
||||||
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
const [snackbarOpen, setSnackbarOpen] = useState(false);
|
||||||
|
@ -44,18 +29,6 @@ const GroupTree = () => {
|
||||||
fetchData();
|
fetchData();
|
||||||
}, [fetchData]);
|
}, [fetchData]);
|
||||||
|
|
||||||
/* const findParent = (element: I_Folder | I_Installation): any => {
|
|
||||||
if (data) {
|
|
||||||
const parent = data.find(
|
|
||||||
(el) => el.type === "Folder" && el.id === element.parentId
|
|
||||||
);
|
|
||||||
if (parent) {
|
|
||||||
return findParent(parent);
|
|
||||||
}
|
|
||||||
return element.parentId;
|
|
||||||
}
|
|
||||||
}; */
|
|
||||||
|
|
||||||
const handleDrop = (
|
const handleDrop = (
|
||||||
newTree: NodeModel<I_Folder | I_Installation>[],
|
newTree: NodeModel<I_Folder | I_Installation>[],
|
||||||
{ dropTargetId, dragSource }: DropOptions<I_Folder | I_Installation>
|
{ dropTargetId, dragSource }: DropOptions<I_Folder | I_Installation>
|
||||||
|
@ -72,7 +45,7 @@ const GroupTree = () => {
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setSnackbarOpen(true);
|
setSnackbarOpen(true);
|
||||||
fetchData();
|
setTree(newTree);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
setPutError(err);
|
setPutError(err);
|
||||||
|
@ -92,7 +65,7 @@ const GroupTree = () => {
|
||||||
<DndProvider backend={MultiBackend} options={getBackendOptions()}>
|
<DndProvider backend={MultiBackend} options={getBackendOptions()}>
|
||||||
<ScrollingComponent className={styles.treeContainer}>
|
<ScrollingComponent className={styles.treeContainer}>
|
||||||
<Tree<I_Installation | I_Folder>
|
<Tree<I_Installation | I_Folder>
|
||||||
tree={getTreeData(data)}
|
tree={tree}
|
||||||
rootId={0}
|
rootId={0}
|
||||||
dragPreviewRender={(monitorProps) => (
|
dragPreviewRender={(monitorProps) => (
|
||||||
<DragPreview monitorProps={monitorProps} />
|
<DragPreview monitorProps={monitorProps} />
|
||||||
|
|
Loading…
Reference in New Issue