diff --git a/app/assets/build.js b/app/assets/build.js old mode 100644 new mode 100755 index 3b7bb554d..7df0f8176 --- a/app/assets/build.js +++ b/app/assets/build.js @@ -1,7 +1,10 @@ +#!/usr/bin/env node + +const aliasGlob = require("./build/esbuild-plugin-alias-glob"); const { copy } = require("esbuild-plugin-copy"); const esbuild = require("esbuild"); -const fs = require("node:fs"); const path = require("node:path"); +const sassMapper = require("./build/sass-mapper"); const { sassPlugin } = require("esbuild-sass-plugin"); const svgr = require("esbuild-plugin-svgr"); @@ -9,6 +12,15 @@ const args = process.argv.slice(2); const watch = args.includes("--watch"); const deploy = args.includes("--deploy"); +const cwd = process.cwd(); + +const elasticsearchIndex = (suffix) => + JSON.stringify( + [process.env.DEV_PREFIX, process.env.DEV_ENV, "dc-v2", suffix] + .filter((e) => e) + .join("-") + ); + const define = { __HONEYBADGER_API_KEY__: JSON.stringify( process.env.HONEYBADGER_API_KEY_FRONTEND || "" @@ -20,11 +32,9 @@ const define = { process.env.HONEYBADGER_REVISION || "" ), __MEADOW_VERSION__: JSON.stringify(process.env.MEADOW_VERSION || ""), - __ELASTICSEARCH_INDEX__: JSON.stringify( - [process.env.DEV_PREFIX, process.env.DEV_ENV, "meadow"] - .filter((e) => e) - .join("-") - ), + __ELASTICSEARCH_WORK_INDEX__: elasticsearchIndex("work"), + __ELASTICSEARCH_COLLECTION_INDEX__: elasticsearchIndex("collection"), + __ELASTICSEARCH_FILE_SET_INDEX__: elasticsearchIndex("file-set"), }; const loader = { @@ -32,24 +42,6 @@ const loader = { ".png": "file", }; -const importMapper = (loc) => { - const relativePathResolver = new RegExp( - "^(?.+?/)(node_modules/.+/)(?node_modules/.+$)" - ); - let result = loc.replace(relativePathResolver, "$$"); - - if (result.startsWith("@")) { - result = path.join(process.cwd(), "node_modules", result); - } - - if (fs.existsSync(path.join(result, "package.json"))) { - const spec = JSON.parse(fs.readFileSync(path.join(result, "package.json"))); - result = path.join(result, spec.sass || spec.main); - } - - return result; -}; - const plugins = [ copy({ assets: { @@ -58,7 +50,12 @@ const plugins = [ }, watch: true, }), - sassPlugin({ cssImports: true, importMapper }), + aliasGlob({ + "@js": { + to: path.resolve(cwd, "./js"), + }, + }), + sassPlugin({ cssImports: true, importMapper: sassMapper }), svgr(), ]; @@ -72,6 +69,7 @@ let opts = { define, loader, plugins, + resolveExtensions: [".mjs", ".js", ".jsx", ".json", ".tsx", ".ts"], }; async function watchMode(opts) { diff --git a/app/assets/build/esbuild-plugin-alias-glob.js b/app/assets/build/esbuild-plugin-alias-glob.js new file mode 100644 index 000000000..4b8a328b4 --- /dev/null +++ b/app/assets/build/esbuild-plugin-alias-glob.js @@ -0,0 +1,39 @@ +const fs = require("node:fs"); +const { globSync } = require("glob"); +const path = require("node:path"); + +const DEFAULT_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js", ".css", ".json"]; + +function indexFile(source) { + const candidate = path.resolve(source, "./index.js"); + if (fs.existsSync(candidate)) return candidate; + return null; +} + +function matchingFile(source, glob) { + const candidates = globSync(`${source}.{${glob}}`); + return candidates[0] || source; +} + +function resolveFile(source, glob) { + return indexFile(source) || matchingFile(source, glob); +} + +module.exports = (specs) => { + return { + name: "aliasGlob", + setup(build) { + for (const alias in specs) { + const { to } = specs[alias]; + const exts = build.initialOptions?.resolveExtensions || DEFAULT_EXTENSIONS; + const fileGlob = exts.join(",").replaceAll(/\./g, "") || ""; + const filter = new RegExp(`^${alias}/`); + build.onResolve({ filter }, async (opts) => { + const source = opts.path.replace(filter, ""); + const result = resolveFile(path.resolve(to, source), fileGlob); + return { path: result }; + }); + } + } + } +}; diff --git a/app/assets/build/sass-mapper.js b/app/assets/build/sass-mapper.js new file mode 100644 index 000000000..59923c3f8 --- /dev/null +++ b/app/assets/build/sass-mapper.js @@ -0,0 +1,20 @@ +const fs = require("node:fs"); +const path = require("node:path"); + +module.exports = (loc) => { + const relativePathResolver = new RegExp( + "^(?.+?/)(node_modules/.+/)(?node_modules/.+$)" + ); + let result = loc.replace(relativePathResolver, "$$"); + + if (result.startsWith("@")) { + result = path.join(process.cwd(), "node_modules", result); + } + + if (fs.existsSync(path.join(result, "package.json"))) { + const spec = JSON.parse(fs.readFileSync(path.join(result, "package.json"))); + result = path.join(result, spec.sass || spec.main); + } + + return result; +}; \ No newline at end of file diff --git a/app/assets/js/components/BatchEdit/Administrative/General.jsx b/app/assets/js/components/BatchEdit/Administrative/General.jsx index a35c1ab6a..082f5e15b 100644 --- a/app/assets/js/components/BatchEdit/Administrative/General.jsx +++ b/app/assets/js/components/BatchEdit/Administrative/General.jsx @@ -1,10 +1,8 @@ -import React from "react"; import PropTypes from "prop-types"; +import React from "react"; import UIFormField from "../../UI/Form/Field"; -import { useFormContext } from "react-hook-form"; import { useCodeLists } from "@js/context/code-list-context"; -import UIFormSelect from "@js/components/UI/Form/Select"; -import UIFormReadingRoomHelperText from "@js/components/UI/Form/ReadingRoomHelperText"; +import { useFormContext } from "react-hook-form"; const BatchEditAdministrativeGeneral = ({ ...restProps }) => { const context = useFormContext(); @@ -96,25 +94,6 @@ const BatchEditAdministrativeGeneral = ({ ...restProps }) => { - - - - ); }; diff --git a/app/assets/js/components/BatchEdit/Confirmation.jsx b/app/assets/js/components/BatchEdit/Confirmation.jsx index 88f3fbd90..aeb487c6b 100644 --- a/app/assets/js/components/BatchEdit/Confirmation.jsx +++ b/app/assets/js/components/BatchEdit/Confirmation.jsx @@ -122,8 +122,7 @@ const BatchEditConfirmation = ({ batchReplaces && (Object.keys(batchReplaces.administrativeMetadata).length > 0 || Object.keys(batchReplaces.descriptiveMetadata).length > 0 || - batchReplaces.published || - Boolean(batchReplaces.readingRoom)); + batchReplaces.published); const hasCollection = batchCollection && Object.keys(batchCollection).length > 0; @@ -211,9 +210,6 @@ const BatchEditConfirmation = ({ ? "Publish works" : "Unpublish works", }), - ...(batchReplaces.readingRoom && { - readingRoom: batchReplaces.readingRoom, - }), }} type="replace" /> diff --git a/app/assets/js/components/BatchEdit/Tabs.jsx b/app/assets/js/components/BatchEdit/Tabs.jsx index 1f131a74d..dc18827be 100644 --- a/app/assets/js/components/BatchEdit/Tabs.jsx +++ b/app/assets/js/components/BatchEdit/Tabs.jsx @@ -187,9 +187,6 @@ export default function BatchEditTabs() { ...((batchPublish.publish || batchPublish.unpublish) && { published: { ...batchPublish }, }), - ...(currentFormValues.readingRoom && { - readingRoom: currentFormValues.readingRoom, - }), descriptiveMetadata: { ...replaceItems.descriptive, ...descriptiveMultiValues.replace, diff --git a/app/assets/js/components/Charts/Visibility.jsx b/app/assets/js/components/Charts/Visibility.jsx index f274a5e8f..9111c62e9 100644 --- a/app/assets/js/components/Charts/Visibility.jsx +++ b/app/assets/js/components/Charts/Visibility.jsx @@ -1,16 +1,17 @@ -import React from "react"; import { - BarChart, Bar, - Cell, - XAxis, - YAxis, + BarChart, CartesianGrid, - Tooltip, + Cell, Legend, ResponsiveContainer, + Tooltip, + XAxis, + YAxis, } from "recharts"; +import React from "react"; + export default function ChartsVisibility({ data = [] }) { return (
diff --git a/app/assets/js/components/Dashboards/BatchEdit/Details.jsx b/app/assets/js/components/Dashboards/BatchEdit/Details.jsx index 0a02533a7..8a87f7b26 100644 --- a/app/assets/js/components/Dashboards/BatchEdit/Details.jsx +++ b/app/assets/js/components/Dashboards/BatchEdit/Details.jsx @@ -1,13 +1,13 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { useQuery } from "@apollo/client"; import { GET_BATCH } from "@js/components/Dashboards/dashboards.gql"; +import { IconImages } from "@js/components/Icon"; import JSONPretty from "react-json-pretty"; -import UIDate from "@js/components/UI/Date"; -import UISkeleton from "@js/components/UI/Skeleton"; import { Link } from "react-router-dom"; -import { IconImages } from "@js/components/Icon"; import { Notification } from "@nulib/design-system"; +import PropTypes from "prop-types"; +import React from "react"; +import UIDate from "@js/components/UI/Date"; +import UISkeleton from "@js/components/UI/Skeleton"; +import { useQuery } from "@apollo/client"; function DashboardsBatchEditDetails({ id }) { const { error, loading, data } = useQuery(GET_BATCH, { @@ -75,7 +75,7 @@ function DashboardsBatchEditDetails({ id }) { className="button is-primary" to={{ pathname: "/search", - state: { passedInSearchTerm: `batches:\"${id}\"` }, + state: { passedInSearchTerm: `batch_ids:\"${id}\"` }, }} > diff --git a/app/assets/js/components/Dashboards/BatchEdit/List.jsx b/app/assets/js/components/Dashboards/BatchEdit/List.jsx index d9213e884..13c691c18 100644 --- a/app/assets/js/components/Dashboards/BatchEdit/List.jsx +++ b/app/assets/js/components/Dashboards/BatchEdit/List.jsx @@ -1,10 +1,11 @@ -import React from "react"; -import { useQuery } from "@apollo/client"; +import { IconImages, IconView } from "@js/components/Icon"; + import { GET_BATCHES } from "@js/components/Dashboards/dashboards.gql"; import { Link } from "react-router-dom"; -import UIDate from "@js/components/UI/Date"; -import { IconImages, IconView } from "@js/components/Icon"; +import React from "react"; import { Tag } from "@nulib/design-system"; +import UIDate from "@js/components/UI/Date"; +import { useQuery } from "@apollo/client"; const colHeaders = [ "Nickname", @@ -80,7 +81,7 @@ export default function DashboardsBatchEditList() { title="View updated works" to={{ pathname: "/search", - state: { passedInSearchTerm: `batches:\"${id}\"` }, + state: { passedInSearchTerm: `batch_ids:\"${id}\"` }, }} > diff --git a/app/assets/js/components/Dashboards/Csv/Details.jsx b/app/assets/js/components/Dashboards/Csv/Details.jsx index 32554b49b..73bf396c4 100644 --- a/app/assets/js/components/Dashboards/Csv/Details.jsx +++ b/app/assets/js/components/Dashboards/Csv/Details.jsx @@ -1,10 +1,10 @@ -import React from "react"; -import PropTypes from "prop-types"; -import UIDate from "@js/components/UI/Date"; import DashboardsCsvErrors from "@js/components/Dashboards/Csv/Errors"; import DashboardsCsvStatus from "@js/components/Dashboards/Csv/Status"; -import { Link } from "react-router-dom"; import { IconImages } from "@js/components/Icon"; +import { Link } from "react-router-dom"; +import PropTypes from "prop-types"; +import React from "react"; +import UIDate from "@js/components/UI/Date"; function DashboardsCsvDetails({ csvMetadataUpdateJob }) { const { @@ -66,7 +66,7 @@ function DashboardsCsvDetails({ csvMetadataUpdateJob }) { to={{ pathname: "/search", state: { - passedInSearchTerm: `metadataUpdateJobs:\"${updateId}\"`, + passedInSearchTerm: `csv_metadata_update_jobs:\"${updateId}\"`, }, }} > diff --git a/app/assets/js/components/Dashboards/Csv/List.jsx b/app/assets/js/components/Dashboards/Csv/List.jsx index 47aa05ca1..397bc0791 100644 --- a/app/assets/js/components/Dashboards/Csv/List.jsx +++ b/app/assets/js/components/Dashboards/Csv/List.jsx @@ -1,13 +1,14 @@ -import React from "react"; +import { IconImages, IconView } from "@js/components/Icon"; + +import DashboardsCsvStatus from "@js/components/Dashboards/Csv/Status"; +import { GET_CSV_METADATA_UPDATE_JOBS } from "@js/components/Dashboards/dashboards.gql"; +import { Link } from "react-router-dom"; import PropTypes from "prop-types"; -import UISearchBarRow from "@js/components/UI/SearchBarRow"; +import React from "react"; import UIFormInput from "@js/components/UI/Form/Input"; -import { useQuery } from "@apollo/client"; -import { GET_CSV_METADATA_UPDATE_JOBS } from "@js/components/Dashboards/dashboards.gql"; +import UISearchBarRow from "@js/components/UI/SearchBarRow"; import { formatDate } from "@js/services/helpers"; -import { Link } from "react-router-dom"; -import { IconImages, IconView } from "@js/components/Icon"; -import DashboardsCsvStatus from "@js/components/Dashboards/Csv/Status"; +import { useQuery } from "@apollo/client"; const displayFields = [ { @@ -125,7 +126,7 @@ function DashboardsCsvList(props) { to={{ pathname: "/search", state: { - passedInSearchTerm: `metadataUpdateJobs:\"${id}\"`, + passedInSearchTerm: `csv_metadata_update_jobs:\"${id}\"`, }, }} > diff --git a/app/assets/js/components/Dashboards/LocalAuthorities/List.jsx b/app/assets/js/components/Dashboards/LocalAuthorities/List.jsx index 1564096a3..124c7efcd 100644 --- a/app/assets/js/components/Dashboards/LocalAuthorities/List.jsx +++ b/app/assets/js/components/Dashboards/LocalAuthorities/List.jsx @@ -1,23 +1,24 @@ -import React from "react"; -import { - useApolloClient, - useMutation, - useQuery, - useLazyQuery, -} from "@apollo/client"; +import { Button, Notification } from "@nulib/design-system"; import { DELETE_NUL_AUTHORITY_RECORD, GET_NUL_AUTHORITY_RECORDS, UPDATE_NUL_AUTHORITY_RECORD, } from "@js/components/Dashboards/dashboards.gql"; -import { AUTHORITIES_SEARCH } from "@js/components/Work/controlledVocabulary.gql"; -import { Button, Notification } from "@nulib/design-system"; +import { IconEdit, IconImages, IconTrashCan } from "@js/components/Icon"; import { Link, useHistory } from "react-router-dom"; -import { toastWrapper } from "@js/services/helpers"; +import { ModalDelete, SearchBarRow } from "@js/components/UI/UI"; +import { + useApolloClient, + useLazyQuery, + useMutation, + useQuery, +} from "@apollo/client"; + +import { AUTHORITIES_SEARCH } from "@js/components/Work/controlledVocabulary.gql"; import DashboardsLocalAuthoritiesModalEdit from "@js/components/Dashboards/LocalAuthorities/ModalEdit"; +import React from "react"; import UIFormInput from "@js/components/UI/Form/Input"; -import { ModalDelete, SearchBarRow } from "@js/components/UI/UI"; -import { IconEdit, IconImages, IconTrashCan } from "@js/components/Icon"; +import { toastWrapper } from "@js/services/helpers"; const colHeaders = ["Label", "Hint"]; @@ -167,9 +168,9 @@ export default function DashboardsLocalAuthoritiesList() { setSearchValue(e.target.value); }; - const handleViewClick = (id) => { + const handleViewClick = (value) => { history.push("/search", { - passedInSearchTerm: `all_controlled_terms:\"${id}\"`, + passedInSearchTerm: `all_controlled_terms:\"${value}\"`, }); }; @@ -221,7 +222,7 @@ export default function DashboardsLocalAuthoritiesList() {