Fix most failures. TODO: Fix frontend/devices/__tests__/reducer_test.ts
parent
c47651282f
commit
f0dcbcd54f
|
@ -1,10 +1,9 @@
|
||||||
import {
|
import {
|
||||||
RootFolderNode as Tree,
|
RootFolderNode as Tree,
|
||||||
FolderUnion,
|
FolderUnion
|
||||||
RootFolderNode
|
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { cloneAndClimb } from "./climb";
|
import { cloneAndClimb } from "./climb";
|
||||||
import { Color, TaggedResource, TaggedSequence } from "farmbot";
|
import { Color } from "farmbot";
|
||||||
import { store } from "../redux/store";
|
import { store } from "../redux/store";
|
||||||
import { initSave, destroy, edit, save, init } from "../api/crud";
|
import { initSave, destroy, edit, save, init } from "../api/crud";
|
||||||
import { Folder } from "farmbot/dist/resources/api_resources";
|
import { Folder } from "farmbot/dist/resources/api_resources";
|
||||||
|
@ -110,113 +109,6 @@ export const updateSearchTerm = (payload: string | undefined) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
interface FolderSearchProps {
|
|
||||||
references: Record<string, TaggedResource | undefined>;
|
|
||||||
input: string;
|
|
||||||
root: RootFolderNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isSearchMatchSeq =
|
|
||||||
(searchTerm: string, s?: TaggedResource): s is TaggedSequence => {
|
|
||||||
if (s && s.kind == "Sequence") {
|
|
||||||
const name = s.body.name.toLowerCase();
|
|
||||||
return name.includes(searchTerm);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const isSearchMatchFolder = (searchTerm: string, f: FolderUnion) => {
|
|
||||||
if (f.name.toLowerCase().includes(searchTerm)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Given an input search term, returns folder IDs (number) and Sequence UUIDs
|
|
||||||
* that match */
|
|
||||||
export const searchFoldersAndSequencesForTerm = (props: FolderSearchProps) => {
|
|
||||||
// A sequence is included if:
|
|
||||||
// * CASE 1: The name is a search match
|
|
||||||
// * CASE 2: The containing folder is a search match.
|
|
||||||
|
|
||||||
// A folder is included if:
|
|
||||||
// * CASE 3: The name is a search match
|
|
||||||
// * CASE 4: It contains a sequence that is a match.
|
|
||||||
// * CASE 5: It has a child that has a search match.
|
|
||||||
|
|
||||||
const searchTerm = props.input.toLowerCase();
|
|
||||||
const sequenceSet = new Set<string>();
|
|
||||||
const folderSet = new Set<FolderUnion>();
|
|
||||||
|
|
||||||
props.root.folders.map(level1 => {
|
|
||||||
level1.content.map(level1Sequence => { // ========= Level 1
|
|
||||||
if (isSearchMatchSeq(searchTerm, props.references[level1Sequence])) {
|
|
||||||
// CASE 1:
|
|
||||||
sequenceSet.add(level1Sequence);
|
|
||||||
// CASE 4:
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isSearchMatchFolder(searchTerm, level1)) {
|
|
||||||
// CASE 2
|
|
||||||
level1.content.map(uuid => sequenceSet.add(uuid));
|
|
||||||
// CASE 3
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
|
|
||||||
level1.children.map(level2 => { // ================ LEVEL 2
|
|
||||||
if (isSearchMatchFolder(searchTerm, level2)) {
|
|
||||||
// CASE 2
|
|
||||||
level2.content.map(uuid => sequenceSet.add(uuid));
|
|
||||||
// CASE 3
|
|
||||||
folderSet.add(level2);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
|
|
||||||
level2.content.map(level2Sequence => {
|
|
||||||
if (isSearchMatchSeq(searchTerm, props.references[level2Sequence])) {
|
|
||||||
// CASE 1:
|
|
||||||
sequenceSet.add(level2Sequence);
|
|
||||||
// CASE 4:
|
|
||||||
folderSet.add(level2);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
level2.children.map(level3 => { // ============== LEVEL 3
|
|
||||||
if (isSearchMatchFolder(searchTerm, level3)) {
|
|
||||||
// CASE 2
|
|
||||||
level3.content.map(uuid => sequenceSet.add(uuid));
|
|
||||||
// CASE 3
|
|
||||||
folderSet.add(level3);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level2);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
level3.content.map(level3Sequence => {
|
|
||||||
if (isSearchMatchSeq(searchTerm, props.references[level3Sequence])) {
|
|
||||||
// CASE 1:
|
|
||||||
sequenceSet.add(level3Sequence);
|
|
||||||
// CASE 3
|
|
||||||
folderSet.add(level3);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level2);
|
|
||||||
// CASE 5
|
|
||||||
folderSet.add(level1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return Array.from(folderSet);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const toggleFolderOpenState = (id: number) => Promise
|
export const toggleFolderOpenState = (id: number) => Promise
|
||||||
.resolve(store.dispatch({ type: Actions.FOLDER_TOGGLE, payload: { id } }));
|
.resolve(store.dispatch({ type: Actions.FOLDER_TOGGLE, payload: { id } }));
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,13 @@ import {
|
||||||
FolderNodeTerminal,
|
FolderNodeTerminal,
|
||||||
RootFolderNode,
|
RootFolderNode,
|
||||||
FolderMeta,
|
FolderMeta,
|
||||||
|
FolderUnion,
|
||||||
} from "./constants";
|
} from "./constants";
|
||||||
import { sortBy } from "lodash";
|
import { sortBy } from "lodash";
|
||||||
|
import {
|
||||||
|
TaggedResource,
|
||||||
|
TaggedSequence
|
||||||
|
} from "farmbot/dist/resources/tagged_resource";
|
||||||
|
|
||||||
type FoldersIndexedByParentId = Record<number, FolderNode[]>;
|
type FoldersIndexedByParentId = Record<number, FolderNode[]>;
|
||||||
|
|
||||||
|
@ -77,3 +82,109 @@ export const ingest: IngestFn = ({ folders, localMetaAttributes }) => {
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
};
|
||||||
|
interface FolderSearchProps {
|
||||||
|
references: Record<string, TaggedResource | undefined>;
|
||||||
|
input: string;
|
||||||
|
root: RootFolderNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isSearchMatchSeq =
|
||||||
|
(searchTerm: string, s?: TaggedResource): s is TaggedSequence => {
|
||||||
|
if (s && s.kind == "Sequence") {
|
||||||
|
const name = s.body.name.toLowerCase();
|
||||||
|
return name.includes(searchTerm);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const isSearchMatchFolder = (searchTerm: string, f: FolderUnion) => {
|
||||||
|
if (f.name.toLowerCase().includes(searchTerm)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Given an input search term, returns folder IDs (number) and Sequence UUIDs
|
||||||
|
* that match */
|
||||||
|
export const searchFoldersAndSequencesForTerm = (props: FolderSearchProps) => {
|
||||||
|
// A sequence is included if:
|
||||||
|
// * CASE 1: The name is a search match
|
||||||
|
// * CASE 2: The containing folder is a search match.
|
||||||
|
|
||||||
|
// A folder is included if:
|
||||||
|
// * CASE 3: The name is a search match
|
||||||
|
// * CASE 4: It contains a sequence that is a match.
|
||||||
|
// * CASE 5: It has a child that has a search match.
|
||||||
|
|
||||||
|
const searchTerm = props.input.toLowerCase();
|
||||||
|
const sequenceSet = new Set<string>();
|
||||||
|
const folderSet = new Set<FolderUnion>();
|
||||||
|
|
||||||
|
props.root.folders.map(level1 => {
|
||||||
|
level1.content.map(level1Sequence => { // ========= Level 1
|
||||||
|
if (isSearchMatchSeq(searchTerm, props.references[level1Sequence])) {
|
||||||
|
// CASE 1:
|
||||||
|
sequenceSet.add(level1Sequence);
|
||||||
|
// CASE 4:
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isSearchMatchFolder(searchTerm, level1)) {
|
||||||
|
// CASE 2
|
||||||
|
level1.content.map(uuid => sequenceSet.add(uuid));
|
||||||
|
// CASE 3
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
|
||||||
|
level1.children.map(level2 => { // ================ LEVEL 2
|
||||||
|
if (isSearchMatchFolder(searchTerm, level2)) {
|
||||||
|
// CASE 2
|
||||||
|
level2.content.map(uuid => sequenceSet.add(uuid));
|
||||||
|
// CASE 3
|
||||||
|
folderSet.add(level2);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
|
||||||
|
level2.content.map(level2Sequence => {
|
||||||
|
if (isSearchMatchSeq(searchTerm, props.references[level2Sequence])) {
|
||||||
|
// CASE 1:
|
||||||
|
sequenceSet.add(level2Sequence);
|
||||||
|
// CASE 4:
|
||||||
|
folderSet.add(level2);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
level2.children.map(level3 => { // ============== LEVEL 3
|
||||||
|
if (isSearchMatchFolder(searchTerm, level3)) {
|
||||||
|
// CASE 2
|
||||||
|
level3.content.map(uuid => sequenceSet.add(uuid));
|
||||||
|
// CASE 3
|
||||||
|
folderSet.add(level3);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level2);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
level3.content.map(level3Sequence => {
|
||||||
|
if (isSearchMatchSeq(searchTerm, props.references[level3Sequence])) {
|
||||||
|
// CASE 1:
|
||||||
|
sequenceSet.add(level3Sequence);
|
||||||
|
// CASE 3
|
||||||
|
folderSet.add(level3);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level2);
|
||||||
|
// CASE 5
|
||||||
|
folderSet.add(level1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Array.from(folderSet);
|
||||||
|
};
|
||||||
|
|
|
@ -24,8 +24,10 @@ import { farmwareState } from "../farmware/reducer";
|
||||||
import { initialState as regimenState } from "../regimens/reducer";
|
import { initialState as regimenState } from "../regimens/reducer";
|
||||||
import { initialState as sequenceState } from "../sequences/reducer";
|
import { initialState as sequenceState } from "../sequences/reducer";
|
||||||
import { initialState as alertState } from "../messages/reducer";
|
import { initialState as alertState } from "../messages/reducer";
|
||||||
// import { searchFoldersAndSequencesForTerm } from "../folders/actions";
|
import {
|
||||||
// import { ingest } from "../folders/data_transfer";
|
ingest,
|
||||||
|
searchFoldersAndSequencesForTerm
|
||||||
|
} from "../folders/data_transfer";
|
||||||
|
|
||||||
export const emptyState = (): RestResources => {
|
export const emptyState = (): RestResources => {
|
||||||
return {
|
return {
|
||||||
|
@ -185,22 +187,22 @@ export const resourceReducer =
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
})
|
})
|
||||||
.add<string | undefined>(Actions.FOLDER_SEARCH, (s/*, { payload }*/) => {
|
.add<string | undefined>(Actions.FOLDER_SEARCH, (s, { payload }) => {
|
||||||
// s.index.sequenceFolders.searchTerm = payload;
|
s.index.sequenceFolders.searchTerm = payload;
|
||||||
// if (payload && payload.length > 2) {
|
if (payload && payload.length > 2) {
|
||||||
// const folders = searchFoldersAndSequencesForTerm({
|
const folders = searchFoldersAndSequencesForTerm({
|
||||||
// references: s.index.references,
|
references: s.index.references,
|
||||||
// input: payload,
|
input: payload,
|
||||||
// root: s.index.sequenceFolders.folders
|
root: s.index.sequenceFolders.folders
|
||||||
// });
|
});
|
||||||
// const nextFolder = ingest({
|
const nextFolder = ingest({
|
||||||
// localMetaAttributes: s.index.sequenceFolders.localMetaAttributes,
|
localMetaAttributes: s.index.sequenceFolders.localMetaAttributes,
|
||||||
// folders
|
folders
|
||||||
// });
|
});
|
||||||
// s.index.sequenceFolders.filteredFolders = nextFolder;
|
s.index.sequenceFolders.filteredFolders = nextFolder;
|
||||||
// } else {
|
} else {
|
||||||
// s.index.sequenceFolders.filteredFolders = undefined;
|
s.index.sequenceFolders.filteredFolders = undefined;
|
||||||
// }
|
}
|
||||||
// reindexFolders(s.index);
|
reindexFolders(s.index);
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue