Skip to content

Commit

Permalink
wipw
Browse files Browse the repository at this point in the history
  • Loading branch information
LasseStaus committed May 22, 2024
1 parent 926b9b9 commit 6ee96b7
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 1 deletion.
7 changes: 7 additions & 0 deletions admin-base.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import "./src/styles/scss/tools";

// CSS sheets that are used to style the admin interface.
@import "./src/stories/Library/opening-hours-editor/opening-hours-editor";
@import "./src/stories/Library/material-search/material-search";
@import "./src/stories/Library/cover/cover";
// CSS sheets that are used to style the admin interface.ssds
1 change: 1 addition & 0 deletions base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
@import "./src/stories/Library/opening-hours/opening-hours-skeleton";
@import "./src/stories/Library/filtered-event-list/filtered-event-list";
@import "./src/stories/Library/event-list-stacked/event-list-stacked";
@import "./src/stories/Library/material-search/material-search";

// Autosuggest block styling needs to be loaded before the rest of the scss for autosuggest
@import "./src/stories/Blocks/autosuggest/autosuggest";
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"css:lint": "concurrently 'yarn:css:stylelint' 'yarn:css:prettier -- --check' --raw",
"css:lint:watch": "chokidar 'src/**/*.scss' -c 'yarn css:lint'",
"css:format": "concurrently 'yarn:css:stylelint -- --fix' 'yarn:css:prettier -- --write' --max-processes 1 --raw",
"css:build": "sass base.scss:src/styles/css/base.css wysiwyg.scss:src/styles/css/wysiwyg.css src/stories/Library/opening-hours-editor/opening-hours-editor.scss:src/styles/css/opening-hours-editor.css --style compressed",
"css:build": "sass base.scss:src/styles/css/base.css wysiwyg.scss:src/styles/css/wysiwyg.css admin-base.scss:src/styles/css/admin-base.css --style compressed",
"css:watch": "yarn css:build -- --watch",
"build": "concurrently 'yarn:css:build' --raw",
"markdown:lint": "markdownlint-cli2",
Expand Down
15 changes: 15 additions & 0 deletions src/stories/Library/material-search/MaterialSearch.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ComponentMeta, ComponentStory } from "@storybook/react";

import MaterialSearch from "./MaterialSearch";

export default {
title: "Library / Material Search",
component: MaterialSearch,
argTypes: {},
} as ComponentMeta<typeof MaterialSearch>;

const Template: ComponentStory<typeof MaterialSearch> = (args) => (
<MaterialSearch {...args} />
);

export const Default = Template.bind({});
41 changes: 41 additions & 0 deletions src/stories/Library/material-search/MaterialSearch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FC, useState } from "react";
import { PreviewData } from "./MaterialSearchExampleData";
import MaterialSearchHiddenInputs from "./MaterialSearchHiddenInputs";
import MaterialSearchInputs from "./MaterialSearchInputs";
import MaterialSearchListResults from "./MaterialSearchListResults";
import MaterialSearchPreview from "./MaterialSearchPreview";

const MaterialSearch: FC = () => {
const [searchInput, setSearchInput] = useState("");
const [selectedWorkId, setSelectedWorkId] = useState("");
const [selectedMaterialType, setSelectedMaterialType] = useState("");

const handleSetSearchInput = (value: string) => {
setSearchInput(value);
setSelectedWorkId(PreviewData.workId);
};

return (
<div className="material-search">
<MaterialSearchHiddenInputs
selectedWorkId={searchInput.length > 1 ? selectedWorkId : ""}
selectedMaterialType={selectedMaterialType}
/>
<MaterialSearchInputs
searchInput={searchInput}
setSearchInput={handleSetSearchInput}
selectedMaterialType={selectedMaterialType}
onMaterialTypeChange={setSelectedMaterialType}
/>
<div className="material-search__materials-wrapper">
<MaterialSearchPreview displayMaterial={searchInput.length > 1} />
<MaterialSearchListResults
onWorkIdSelect={(workId) => setSelectedWorkId(workId)}
showListResults={searchInput.length > 1}
/>
</div>
</div>
);
};

export default MaterialSearch;
69 changes: 69 additions & 0 deletions src/stories/Library/material-search/MaterialSearchExampleData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
export const MaterialTypes = [
"bog",
"artikel",
"tidsskrift",
"lydbog",
"film",
"musik",
"spil",
];

export interface PreviewDataProps {
coverUrl: string;
title: string;
author: string;
publicationYear: number;
source: string;
workId: string;
}
export const PreviewData: PreviewDataProps = {
coverUrl: "images/book_cover_6.jpg",
title: "Rødhals",
author: "Jo Nesbø",
publicationYear: 2022,
source: "InterLibraryLoan",
workId: "work-of:800010-katalog:99122475830405763",
};

export const ListResultData: PreviewDataProps[] = [
{
coverUrl: "images/book_cover_1.jpg",
title: "Book Title 1",
author: "Author 1",
publicationYear: 2021,
source: "Library",
workId: "work-of:800010-katalog:99122475830405761",
},
{
coverUrl: "images/book_cover_2.jpg",
title: "Book Title 2",
author: "Author 2",
publicationYear: 2020,
source: "InterLibraryLoan",
workId: "work-of:800010-katalog:2389129",
},
{
coverUrl: "images/book_cover_3.jpg",
title: "Book Title 3",
author: "Author 3",
publicationYear: 2019,
source: "Library",
workId: "work-of:800010-katalog:98432897",
},
{
coverUrl: "images/book_cover_4.jpg",
title: "Book Title 4",
author: "Author 4",
publicationYear: 2018,
source: "InterLibraryLoan",
workId: "work-of:800010-katalog:9778817",
},
{
coverUrl: "images/book_cover_5.jpg",
title: "Book Title 5",
author: "Author 5",
publicationYear: 2017,
source: "Library",
workId: "work-of:800010-katalog:2093",
},
];
42 changes: 42 additions & 0 deletions src/stories/Library/material-search/MaterialSearchHiddenInputs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
interface MaterialSearchHiddenInputsProps {
selectedWorkId: string;
selectedMaterialType: string;
}

const MaterialSearchHiddenInputs = ({
selectedWorkId,
selectedMaterialType,
}: MaterialSearchHiddenInputsProps) => {
// These hidden inputs are used to store the selected work ID and material type in the drupal form
// In react, they are located in the storybook component, but in the drupal form they are created in the field widget and hidden with css.
return (
<div className="material-search__inputs-container">
<label className="material-search__label" htmlFor="hidden-work-id-input">
Hidden Work ID field
<input
id="hidden-work-id-input"
type="text"
value={selectedWorkId}
placeholder="Enter search terms"
className="material-search__input"
disabled
/>
</label>
<label
className="material-search__label"
htmlFor="hidden-material-type-input"
>
Hidden Material Type field
<input
type="text"
id="hidden-material-type-input"
value={selectedMaterialType}
className="material-search__input"
disabled
/>
</label>
</div>
);
};

export default MaterialSearchHiddenInputs;
55 changes: 55 additions & 0 deletions src/stories/Library/material-search/MaterialSearchInputs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { MaterialTypes } from "./MaterialSearchExampleData";

interface MaterialSearchInputsProps {
searchInput: string;
selectedMaterialType: string;
setSearchInput: (value: string) => void;
onMaterialTypeChange: (value: string) => void;
}

const MaterialSearchInputs = ({
searchInput,
selectedMaterialType,
setSearchInput,
onMaterialTypeChange,
}: MaterialSearchInputsProps) => {
return (
<div className="material-search__inputs-container">
<label className="material-search__label" htmlFor="material-search-input">
Search for materials
<input
id="material-search-input"
type="search"
value={searchInput}
onChange={(e) => setSearchInput(e.target.value)}
placeholder="Enter search terms"
className="material-search__input"
/>
</label>
<label
className="material-search__label"
htmlFor="material-type-selector"
>
Choose material type
<select
id="material-type-selector"
className="material-search__selector"
disabled={!searchInput}
onChange={(e) => onMaterialTypeChange(e.target.value)}
value={selectedMaterialType || ""}
>
<option value="" disabled>
-- Choose material type --
</option>
{MaterialTypes.map((materialType: string) => (
<option key={materialType} value={materialType}>
{materialType}
</option>
))}
</select>
</label>
</div>
);
};

export default MaterialSearchInputs;
62 changes: 62 additions & 0 deletions src/stories/Library/material-search/MaterialSearchListResults.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Cover from "../cover/Cover";
import { ListResultData } from "./MaterialSearchExampleData";
import MaterialSearchLoading from "./MaterialSearchLoading";

interface MaterialSearchListResultsProps {
onWorkIdSelect: (workId: string) => void;
showListResults: boolean;
}

const MaterialSearchListResults = ({
onWorkIdSelect,
showListResults,
}: MaterialSearchListResultsProps) => {
const handleClickOnListItem = (workId: string) => {
onWorkIdSelect(workId);
};

return !showListResults ? (
<div>No results found.</div>
) : (
<div className="material-search__list">
<div className="material-search__list-header">Total results: 5</div>
<ul className="material-search__list-results">
{ListResultData.map((work) => {
return (
<li key={work.workId}>
<button
className="material-search__list-result-button"
data-work-id={work.workId}
onClick={() => handleClickOnListItem(work.workId)}
onKeyPress={(e) => {
if (e.key === "Enter") {
handleClickOnListItem(work.workId);
}
}}
>
<div className="material-search__list-result-image-content">
<Cover size="xsmall" src={work.coverUrl} animate />
</div>
<div className="material-search__list-result-content">
<span className="material-search__preview-content__label">
Title:
</span>
<span>{work.title}</span>
<span className="material-search__preview-content__label">
Author:
</span>
<span>{work.author}</span>
</div>
</button>
</li>
);
})}
<li className="material-search__list-result--loading">
<MaterialSearchLoading loadingText="Loading..." />
</li>
</ul>
</div>
);
};

export default MaterialSearchListResults;
22 changes: 22 additions & 0 deletions src/stories/Library/material-search/MaterialSearchLoading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import LoadingLogo from "../../../public/icons/logo/reload_logo_black.svg";

interface ReloadLoadingIconProps {
loadingText?: string;
}

const MaterialSearchLoading = ({ loadingText }: ReloadLoadingIconProps) => {
return (
<div className="material-search__loading">
<img
src={LoadingLogo}
alt="Loading..."
className="material-search__loading-spinner"
/>
{loadingText && (
<span className="material-search__loading-text">{loadingText}</span>
)}
</div>
);
};

export default MaterialSearchLoading;
Loading

0 comments on commit 6ee96b7

Please sign in to comment.