Skip to content

Commit

Permalink
Merge Embed in external website #46
Browse files Browse the repository at this point in the history
  • Loading branch information
MiraGeowerkstatt authored Aug 22, 2022
2 parents 1bcbe0b + e9645e7 commit 7307bc9
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 13 deletions.
3 changes: 2 additions & 1 deletion src/ClientApp/src/components/Detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export function Detail() {
const navigate = useNavigate();
const { md5, name } = useParams();

const backToSearch = () => navigate(`/?query=${location.state.query}`, { replace: true });
const backToSearch = () =>
navigate(`/?query=${location.state.query}&hideFilter=${location.state.hideFilter}`, { replace: true });
const toHome = () => navigate("/");

useEffect(() => {
Expand Down
136 changes: 136 additions & 0 deletions src/ClientApp/src/components/EmbedDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import React, { useState } from "react";
import {
Button,
Dialog,
DialogTitle,
DialogActions,
DialogContent,
DialogContentText,
IconButton,
Stack,
Switch,
TextField,
Tooltip,
} from "@mui/material";
import FormGroup from "@mui/material/FormGroup";
import FormControlLabel from "@mui/material/FormControlLabel";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import { useTranslation } from "react-i18next";
import InputAdornment from "@mui/material/InputAdornment";

export function EmbedDialog(props) {
const { open, setOpen } = props;
const [width, setWidth] = useState(900);
const [height, setHeight] = useState(750);
const [border, setBorder] = useState(true);
const [hideFilter, setHideFilter] = useState(false);
const { t } = useTranslation("common");

const handleClose = () => {
setOpen(false);
};

return (
<Dialog open={open} onClose={handleClose} fullWidth={true} maxWidth="lg">
<DialogTitle>{t("generate-embed-tag")}</DialogTitle>
<DialogContent>
<DialogContentText>{t("generate-embed-tag-instructions")}</DialogContentText>
<Stack mt={5} direction="row" justifyContent="flex-start" alignItems="flex-end">
<TextField
margin="dense"
onChange={(e) => setWidth(e.target.value)}
InputProps={{
endAdornment: <InputAdornment position="start">px</InputAdornment>,
}}
value={width}
label={t("width")}
sx={{ marginRight: 5 }}
type="number"
variant="standard"
/>
<TextField
margin="dense"
onChange={(e) => setHeight(e.target.value)}
InputProps={{
endAdornment: <InputAdornment position="start">px</InputAdornment>,
}}
value={height}
label={t("height")}
sx={{ marginRight: 5 }}
type="number"
variant="standard"
/>
<FormGroup>
<FormControlLabel
control={<Switch checked={border} onChange={(e) => setBorder(e.target.checked)} />}
label={t("border")}
/>
</FormGroup>
<FormGroup>
<FormControlLabel
control={<Switch checked={hideFilter} onChange={(e) => setHideFilter(e.target.checked)} />}
label={t("hide-filter")}
/>
</FormGroup>
</Stack>
<Stack mt={5} direction="row" alignItems="flex-end">
<TextField
value={`<iframe src="https://ilimodels.ch${
hideFilter ? "/?hideFilter=true" : ""
}" width="${width}" height="${height}" style="border: ${
border ? "1px solid darkgrey" : "none"
} " sandbox="allow-scripts allow-same-origin allow-storage-access-by-user-activation allow-forms"></iframe>`}
sx={{ bgcolor: "action.hover", marginTop: 5 }}
type="text"
fullWidth
variant="outlined"
/>
<Tooltip title={t("copy-to-clipboard")}>
<IconButton
onClick={() => {
navigator.clipboard.writeText(
`<iframe src="https://ilimodels.ch${
hideFilter ? "/?hideFilter=true" : ""
}" width="${width}" height="${height}" style="border: ${
border ? "1px solid darkgrey" : "none"
} " sandbox="allow-scripts allow-same-origin allow-storage-access-by-user-activation allow-forms"></iframe>`
);
}}
>
<ContentCopyIcon />
</IconButton>
</Tooltip>
</Stack>
<Stack direction="row" alignItems="flex-end">
<TextField
value={`<embed type="text/html" src="https://ilimodels.ch${
hideFilter ? "/?hideFilter=true" : ""
}" width="${width}" height="${height}" style="border: ${border ? "1px solid darkgrey" : "none"}"></embed>`}
sx={{ bgcolor: "action.hover", marginTop: 5 }}
type="text"
fullWidth
variant="outlined"
/>
<Tooltip title={t("copy-to-clipboard")}>
<IconButton
onClick={() => {
navigator.clipboard.writeText(
`<embed type="text/html" src="https://ilimodels.ch${
hideFilter ? "/?hideFilter=true" : ""
}" width="${width}" height="${height}" style="border: ${
border ? "1px solid darkgrey" : "none"
}"></embed>`
);
}}
>
<ContentCopyIcon />
</IconButton>
</Tooltip>
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>{t("close")}</Button>
</DialogActions>
</Dialog>
);
}
14 changes: 13 additions & 1 deletion src/ClientApp/src/components/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ export function Home() {
const [searchParams, setSearchParams] = useSearchParams();
const [models, setModels] = useState(null);
const [inputValue, setInputValue] = useState(searchParams.get("query") || "");
const [hideFilter, setHideFilter] = useState(false);
const [repositoryTree, setRepositoryTree] = useState();
const [searchOptions, setSearchOptions] = useState([]);
const [loading, setLoading] = useState();

const { t } = useTranslation("common");

async function search(searchString) {
// Use hideFilter state for query if it was not explicitly set in url.
if (searchParams.get("hideFilter") === undefined) {
searchString += "&hideFilter=" + !!hideFilter;
}
setSearchParams(
{
query: searchString,
Expand Down Expand Up @@ -77,7 +82,9 @@ export function Home() {
};

// If component is first loaded with search params present in URL the search should immediately be executed.
// On first load the hideFilter state should be set for all following requests.
useEffect(() => {
setHideFilter(searchParams.get("hideFilter"));
if (inputValue !== "") {
search(inputValue);
}
Expand Down Expand Up @@ -148,7 +155,12 @@ export function Home() {
</Box>
)}
{models !== null && (
<Results models={models} repositoryTree={repositoryTree} searchParams={searchParams}></Results>
<Results
hideFilter={hideFilter === "true"}
models={models}
repositoryTree={repositoryTree}
searchParams={searchParams}
></Results>
)}
</Box>
);
Expand Down
17 changes: 15 additions & 2 deletions src/ClientApp/src/components/Layout.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import React, { useEffect, useState } from "react";
import { AppBar, Container, Toolbar, Typography } from "@mui/material";
import { Box } from "@mui/system";
import CodeIcon from "@mui/icons-material/Code";
import { AppBar, Box, Container, Toolbar, Tooltip, Typography } from "@mui/material";
import { EmbedDialog } from "./EmbedDialog";
import { useTranslation } from "react-i18next";

export function Layout(props) {
const [version, setVersion] = useState();
const [open, setOpen] = useState(false);
const { t } = useTranslation("common");

const handleClickOpen = () => {
setOpen(true);
};

useEffect(() => {
async function fetchData() {
const response = await fetch("/version");
Expand All @@ -19,13 +28,17 @@ export function Layout(props) {
<AppBar position="static">
<Toolbar>
<Typography sx={{ flexGrow: 1 }}>INTERLIS Model Repo Browser</Typography>
<Tooltip title={t("generate-embed-tag")}>
<CodeIcon sx={{ marginBottom: 0.5, marginRight: 1 }} onClick={handleClickOpen}></CodeIcon>
</Tooltip>
<Typography variant="caption" gutterBottom>
Version: {version}
</Typography>
</Toolbar>
</AppBar>
</Box>
<Container>{props.children}</Container>
<EmbedDialog open={open} setOpen={setOpen}></EmbedDialog>
</div>
);
}
14 changes: 8 additions & 6 deletions src/ClientApp/src/components/Results.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { useTranslation } from "react-i18next";
import { Filter } from "./Filter";

export function Results(props) {
const { models, repositoryTree, searchParams } = props;
const { models, repositoryTree, searchParams, hideFilter } = props;
const { t } = useTranslation("common");
const [page, setPage] = useState(1);
const [showFilter, setShowFilter] = useState(false);
Expand Down Expand Up @@ -41,11 +41,13 @@ export function Results(props) {
<Typography variant="h4" mt={6} ml={1}>
{filteredModels.length + " " + t("models-found", { count: filteredModels.length })}
</Typography>
<Button variant="outlined" startIcon={<FilterAltIcon />} onClick={toggleFilter}>
{t("filter")}
</Button>
{!hideFilter && (
<Button variant="outlined" startIcon={<FilterAltIcon />} onClick={toggleFilter}>
{t("filter")}
</Button>
)}
</Stack>
{showFilter && (
{showFilter && !hideFilter && (
<Filter
models={models}
filteredModels={filteredModels}
Expand All @@ -67,7 +69,7 @@ export function Results(props) {
to={{
pathname: "/detail/" + model.mD5 + "/" + model.name,
}}
state={{ query: searchParams.get("query") }}
state={{ query: searchParams.get("query"), hideFilter: hideFilter }}
>
{model.name}
</Link>
Expand Down
10 changes: 9 additions & 1 deletion src/ClientApp/src/translations/de/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,13 @@
"model-preview": "Modellvorschau",
"invalid-model-url": "Ungültige Modell-URL",
"no-model-preview": "Keine Modellvorschau verfügbar",
"model-uri": "Modell-URI"
"model-uri": "Modell-URI",
"width": "Breite",
"height": "Höhe",
"generate-embed-tag": "iFrame oder Embed-Tag zum Einbetten in externe Webseite generieren",
"generate-embed-tag-instructions": "Für ein optimales Ergebnis empfehlen wir eine minimale Breite von 900px und eine minimale Höhe von 750px.",
"border": "Rahmen",
"copy-to-clipboard": "In die Zwischenablage kopieren",
"close": "Schliessen",
"hide-filter": "Filterbereich ausblenden"
}
10 changes: 9 additions & 1 deletion src/ClientApp/src/translations/fr/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,13 @@
"model-preview": "Aperçu du modèle",
"invalid-model-url": "URL de modèle non valide",
"no-model-preview": "Aucun aperçu du modèle disponible",
"model-uri": "URI du modèle"
"model-uri": "URI du modèle",
"width": "Largeur",
"height": "Hauteur",
"generate-embed-tag": "Générer iFrame ou embed-tag pour l'intégration dans un site web externe",
"generate-embed-tag-instructions": "Pour un résultat optimal, nous recommandons une largeur minimale de 900px et une hauteur minimale de 750px.",
"border": "Encadrement",
"copy-to-clipboard": "Copier dans le Presse-papiers",
"close": "Fermer",
"hide-filter": "Masquer le panneau de filtre"
}
10 changes: 9 additions & 1 deletion src/ClientApp/src/translations/it/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,13 @@
"model-preview": "Anteprima del modello",
"invalid-model-url": "URL del modello non valido",
"no-model-preview": "Nessuna anteprima del modello disponibile",
"model-uri": "URI del modello"
"model-uri": "URI del modello",
"width": "Larghezza",
"height": "Altezza",
"generate-embed-tag": "Genera iFrame o embed-tag da incorporare in un sito web esterno",
"generate-embed-tag-instructions": "Per ottenere i migliori risultati, consigliamo una larghezza minima di 900px e un'altezza minima di 750px.",
"border": "Telaio",
"copy-to-clipboard": "Copia negli appunti",
"close": "Chiudere",
"hide-filter": "Nascondi pannello filtro"
}

0 comments on commit 7307bc9

Please sign in to comment.