Skip to content

Commit

Permalink
feat: local slpk feature (#391)
Browse files Browse the repository at this point in the history
  • Loading branch information
dariaterekhova-actionengine authored Dec 17, 2024
1 parent bc3d4ea commit 03dab00
Show file tree
Hide file tree
Showing 25 changed files with 459 additions and 263 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module.exports = {
},
parser: "@typescript-eslint/parser",
extends: ["standard-with-typescript", "plugin:react/recommended"],
// ignorePatterns: ["**/*.html"],
ignorePatterns: ["**/*.slpk"],
overrides: [
{
env: {
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/react-fontawesome": "^0.1.17",
"@hyperjump/json-schema": "^0.23.2",
"@loaders.gl/3d-tiles": "^4.1.0-alpha.11",
"@loaders.gl/core": "^4.1.0-alpha.11",
"@loaders.gl/i3s": "^4.1.0-alpha.11",
"@loaders.gl/tiles": "^4.1.0-alpha.11",
"@loaders.gl/loader-utils": "^4.3.3",
"@loaders.gl/3d-tiles": "^4.3.3",
"@loaders.gl/core": "^4.3.3",
"@loaders.gl/i3s": "^4.3.3",
"@loaders.gl/tiles": "^4.3.3",
"@luma.gl/core": "^8.5.14",
"@math.gl/core": "^3.6.0",
"@math.gl/proj4": "^3.6.3",
Expand Down Expand Up @@ -113,7 +114,7 @@
"webpack-dev-server": "^5.0.4"
},
"resolutions": {
"@loaders.gl/tiles": "^4.1.0-alpha.11"
"@loaders.gl/tiles": "^4.3.3"
},
"volta": {
"node": "18.18.2",
Expand Down
6 changes: 6 additions & 0 deletions src/components/bookmarks-panel/bookmarks-panel.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ jest.mock("../../utils/hooks/layout");

const dragAndDropText = "Drag and drop your json file here";

Object.defineProperty(globalThis, "crypto", {
value: {
randomUUID: () => "",
},
});

const TEST_BOOKMARKS = [
{
id: "testId1",
Expand Down
8 changes: 5 additions & 3 deletions src/components/bookmarks-panel/bookmarks-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,11 @@ export const BookmarksPanel = ({
onEditBookmarks={onEditBookmarksClickHandler}
onClearBookmarks={onClearBookmarksClickHandler}
onUploadBookmarks={() => {
setPopoverType(
bookmarks.length ? PopoverType.uploadWarning : PopoverType.upload
);
setTimeout(() => {
setPopoverType(
bookmarks.length ? PopoverType.uploadWarning : PopoverType.upload
);
}, 1);
}}
onDownloadBookmarks={onDownloadBookmarks}
onCollapsed={onCollapsed}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ describe("UnsavedBookmarkWarning", () => {
const { container } = callRender(renderWithTheme);
const fileInteractionContiner = container.firstChild.firstChild;
expect(container.firstChild).toBeInTheDocument();
expect(fileInteractionContiner.childNodes.length).toBe(3);
expect(fileInteractionContiner.childNodes.length).toBe(2);
});
});
17 changes: 13 additions & 4 deletions src/components/comparison/comparison-side/comparison-side.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { parseTilesetUrlParams } from "../../../utils/url-utils";
import {
findExampleAndUpdateWithViewState,
getActiveLayersByIds,
getLayerUrl,
handleSelectAllLeafsInGroup,
selectNestedLayers,
} from "../../../utils/layer-utils";
Expand Down Expand Up @@ -234,7 +235,13 @@ export const ComparisonSide = ({
const tilesetsData: TilesetMetadata[] = [];

for (const layer of activeLayers) {
const params = parseTilesetUrlParams(layer.url, layer);
let params = { tilesetUrl: "" as string | File, token: "" };
if (typeof layer.url === "string") {
params = parseTilesetUrlParams(layer.url, layer);
} else {
params.tilesetUrl = layer.url;
}

const { tilesetUrl, token } = params;

tilesetsData.push({
Expand All @@ -254,8 +261,9 @@ export const ComparisonSide = ({
})
);
if (buildingExplorerOpened && tilesetsData[0]) {
const tilesetDataUrl = getLayerUrl(tilesetsData[0].url);
void dispatch(
getBSLStatisticsSummary({ statSummaryUrl: tilesetsData[0].url, side })
getBSLStatisticsSummary({ statSummaryUrl: tilesetDataUrl, side })
);
}
}, [activeLayers, buildingExplorerOpened]);
Expand All @@ -279,7 +287,7 @@ export const ComparisonSide = ({

if (loadedTilesetsCount && activeLayersCount) {
const isBSL = loadedTilesetsCount > activeLayersCount;
let statsName = activeLayers[0].url;
let statsName = getLayerUrl(activeLayers[0].url);

if (!isBSL) {
statsName = loadedTilesets
Expand Down Expand Up @@ -312,12 +320,13 @@ export const ComparisonSide = ({
.map((sublayer) => ({
id: sublayer.id,
url: sublayer.url,
fetch: sublayer.fetch,
token: sublayer.token,
type: sublayer.type ?? TilesetType.I3S,
}));
};

const onTraversalCompleteHandler = (selectedTiles) => {
const onTraversalCompleteHandler = (selectedTiles: Tile3D[]) => {
// A parent tileset of selected tiles
const aTileset = selectedTiles?.[0]?.tileset;
// Make sure that the actual tileset has been traversed traversed
Expand Down
1 change: 1 addition & 0 deletions src/components/deck-gl-wrapper/deck-gl-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ interface DeckGlI3sProps {
layers3d: Array<{
id?: number;
url?: string;
fetch?: ((input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>);
token?: string | null;
type: TilesetType;
}>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import "@testing-library/jest-dom";
const onInsertMock = jest.fn();
const onCancelMock = jest.fn();

Object.defineProperty(globalThis, "crypto", {
value: {
randomUUID: () => "",
},
});

const callRender = (
renderFunc,
props = {},
Expand Down
65 changes: 44 additions & 21 deletions src/components/layers-panel/insert-panel/insert-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type LayoutProps,
TilesetType,
BaseMapGroup,
FileType,
} from "../../../types";
import {
getCurrentLayoutProperty,
Expand All @@ -23,20 +24,23 @@ import {
getLayerNameInfo,
selectLayerNames,
} from "../../../redux/slices/layer-names-slice";
import { UploadPanel } from "../../upload-panel/upload-panel";
import { getLayerUrl } from "../../../utils/layer-utils";

const NO_NAME_ERROR = "Please enter name";
const INVALID_URL_ERROR = "Invalid URL";

export interface CustomLayerData {
name: string;
url: string;
url: string | File;
token?: string;
group?: BaseMapGroup;
}

interface InsertLayerProps {
title: string;
groups?: string[];
noFile?: boolean;
onInsert: (object: CustomLayerData) => Promise<void> | void;
onCancel: () => void;
children?: React.ReactNode;
Expand Down Expand Up @@ -101,13 +105,14 @@ const SpinnerContainer = styled.div<VisibilityProps>`
export const InsertPanel = ({
title,
groups,
noFile,
onInsert,
onCancel,
children = null,
}: InsertLayerProps) => {
const [group, setGroup] = useState<BaseMapGroup>(BaseMapGroup.Maplibre);
const [name, setName] = useState("");
const [url, setUrl] = useState("");
const [url, setUrl] = useState<string | File>("");
const [token, setToken] = useState("");

const [nameError, setNameError] = useState("");
Expand All @@ -116,29 +121,33 @@ export const InsertPanel = ({
const layerNames = useAppSelector(selectLayerNames);
const dispatch = useAppDispatch();

const getNewLayerUrl = () => getLayerUrl(url);

const validateFields = (): void => {
let isFormValid = true;
const type = getTilesetType(url);
const type = getTilesetType(typeof url === "string" ? url : url.name);

try {
// eslint-disable-next-line no-new
new URL(url);
} catch (_) {
setUrlError(INVALID_URL_ERROR);
isFormValid = false;
if (typeof url === "string") {
try {
// eslint-disable-next-line no-new
new URL(url);
} catch (_) {
setUrlError(INVALID_URL_ERROR);
isFormValid = false;
}
}

if (
(type !== TilesetType.I3S && !name) ||
(type === TilesetType.I3S && !name && !layerNames[url]?.name)
(type === TilesetType.I3S && !name && !layerNames[getNewLayerUrl()]?.name)
) {
setNameError(NO_NAME_ERROR);
isFormValid = false;
}

if (isFormValid) {
void onInsert({
name: name || layerNames[url]?.name,
name: name || layerNames[getNewLayerUrl()]?.name,
url,
token,
group: groups ? group : undefined,
Expand All @@ -147,16 +156,16 @@ export const InsertPanel = ({
};

useEffect(() => {
const type = getTilesetType(url);
const type = getTilesetType(getNewLayerUrl());
if (isValidateInProgress && type === TilesetType.I3S) {
if (
(layerNames[url] !== undefined &&
layerNames[url].status === FetchingStatus.ready) ||
(layerNames[getNewLayerUrl()] !== undefined &&
layerNames[getNewLayerUrl()].status === FetchingStatus.ready) ||
name.length > 0
) {
setValidateInProgress(false);
validateFields();
} else if (!layerNames[url]) {
} else if (!layerNames[getNewLayerUrl()]) {
void dispatch(getLayerNameInfo({ layerUrl: url, token, type }));
}
}
Expand All @@ -165,27 +174,34 @@ export const InsertPanel = ({
const handleInsert = (event) => {
event.preventDefault();

if (getTilesetType(url) !== TilesetType.I3S) {
if (getTilesetType(getNewLayerUrl()) !== TilesetType.I3S) {
validateFields();
} else {
setValidateInProgress(true);
}
};

const handleInputChange = (event) => {
const { name, value } = event.target;
const { name: fieldName, value, files } = event.target;

switch (name) {
switch (fieldName) {
case "BasemapProvider":
setGroup(value);
setGroup(value as BaseMapGroup);
setNameError("");
break;
case "Name":
setName(value);
setNameError("");
break;
case "URL":
setUrl(value);
if (files) {
setUrl(files[0]);
if (!name) {
setName(files[0].name.substring(0, files[0].name.length - 5));
}
} else {
setUrl(value);
}
setUrlError("");
break;
case "Token":
Expand Down Expand Up @@ -225,7 +241,7 @@ export const InsertPanel = ({
<InputText
name="URL"
label="URL"
value={url}
value={typeof url === "string" ? url : ""}
error={urlError}
onChange={handleInputChange}
/>
Expand All @@ -235,6 +251,13 @@ export const InsertPanel = ({
value={token}
onChange={handleInputChange}
/>
{!noFile && <UploadPanel
dragAndDropText={"Drag and drop your .slpk file here"}
noPadding={true}
accept=".slpk"
onFileEvent={(files) => { handleInputChange({ target: { files, name: "URL" } }); }}
fileType={FileType.binary}
/>}
</InputsWrapper>
<ButtonsWrapper>
<ActionButton
Expand Down
Loading

0 comments on commit 03dab00

Please sign in to comment.