Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby-admin): plugin search #25903

Merged
merged 7 commits into from
Jul 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/gatsby-admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@
"@emotion/styled": "^10.0.27",
"@typescript-eslint/eslint-plugin": "^2.28.0",
"@typescript-eslint/parser": "^2.28.0",
"@types/react-instantsearch-dom": "^5.2.6",
"csstype": "^2.6.10",
"formik": "^2.1.4",
"gatsby": "^2.24.7",
"gatsby-interface": "0.0.173",
"gatsby-plugin-typescript": "^2.4.16",
"gatsby-source-graphql": "^2.6.2",
"lodash-es": "^4.17.15",
"ncp": "^2.0.0",
"nodemon": "^2.0.4",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-helmet": "^6.1.0",
"react-icons": "^3.10.0",
"react-instantsearch-dom": "^5.7.0",
"remove-markdown": "^0.3.0",
"strict-ui": "^0.1.3",
"subscriptions-transport-ws": "^0.9.16",
"theme-ui": "^0.4.0-alpha.3",
Expand Down
106 changes: 106 additions & 0 deletions packages/gatsby-admin/src/components/plugin-search.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* @jsx jsx */
import { jsx } from "strict-ui"
import { Spinner } from "theme-ui"
import {
InstantSearch,
Configure,
RefinementList,
ToggleRefinement,
connectAutoComplete,
} from "react-instantsearch-dom"
import {
Combobox,
ComboboxInput,
ComboboxPopover,
ComboboxList,
ComboboxOption,
} from "gatsby-interface"
import { useMutation } from "urql"

const SearchCombobox: React.FC<{
onSelect: (value: string) => void
}> = connectAutoComplete(({ hits, currentRefinement, refine, onSelect }) => (
<Combobox onSelect={onSelect}>
<ComboboxInput
sx={{ width: `20em` }}
aria-labelledby="plugin-search-label"
onChange={(e): void => refine(e.target.value)}
value={currentRefinement}
/>
<ComboboxPopover>
<ComboboxList aria-labelledby="plugin-search-label">
{hits.map(hit => (
<ComboboxOption
key={hit.objectID}
selected={false}
value={hit.name}
></ComboboxOption>
))}
</ComboboxList>
</ComboboxPopover>
</Combobox>
))

// the search bar holds the Search component in the InstantSearch widget
const PluginSearchInput: React.FC<{}> = () => {
const [{ fetching }, installGatbyPlugin] = useMutation(`
mutation installGatsbyPlugin($name: String!) {
createNpmPackage(npmPackage: {
name: $name,
dependencyType: "production"
}) {
id
name
}
createGatsbyPlugin(gatsbyPlugin: {
name: $name
}) {
id
name
}
}
`)

return (
<div>
<InstantSearch
apiKey="ae43b69014c017e05950a1cd4273f404"
appId="OFCNCOG2CU"
indexName="npm-search"
>
<div style={{ display: `none` }}>
<Configure analyticsTags={[`gatsby-plugins`]} />
<RefinementList
attribute="keywords"
transformItems={(items: Array<any>): Array<any> =>
items.map(({ count, ...item }) => {
return {
...item,
count: count || 0,
}
})
}
defaultRefinement={[`gatsby-component`, `gatsby-plugin`]}
/>
<ToggleRefinement
attribute="deprecated"
value={false}
label="No deprecated plugins"
defaultRefinement={true}
/>
</div>
{fetching ? (
<Spinner />
) : (
<SearchCombobox
onSelect={(value): void => {
installGatbyPlugin({ name: value })
}}
/>
)}
</InstantSearch>
</div>
)
}

export default PluginSearchInput
1 change: 1 addition & 0 deletions packages/gatsby-admin/src/components/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const theme = {
"100%": `100%`,
"16px": `16px`,
"15em": `15em`,
"20em": `20em`,
initial: `initial`,
},
}
Expand Down
87 changes: 7 additions & 80 deletions packages/gatsby-admin/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,18 @@
/** @jsx jsx */
import React from "react"
import { jsx, Flex, Grid } from "strict-ui"
import { Spinner } from "theme-ui"
import { useQuery, useMutation } from "urql"
import {
Heading,
HeadingProps,
Text,
Button,
InputField,
InputFieldControl,
ButtonProps,
InputFieldLabel,
DropdownMenu,
DropdownMenuButton,
DropdownMenuItem,
DropdownMenuItems,
} from "gatsby-interface"

const SecondaryButton: React.FC<ButtonProps> = props => (
<Button
variant="SECONDARY"
size="S"
sx={{
paddingX: 6,
paddingY: 4,
}}
{...props}
></Button>
)

const InstallInput: React.FC<{ for: string }> = props => {
const inputId = `install-${props.for}`
const [value, setValue] = React.useState(``)

const [{ fetching }, installGatbyPlugin] = useMutation(`
mutation installGatsbyPlugin($name: String!) {
createNpmPackage(npmPackage: {
name: $name,
dependencyType: "production"
}) {
id
name
}
createGatsbyPlugin(gatsbyPlugin: {
name: $name
}) {
id
name
}
}
`)

return (
<form
onSubmit={(evt): void => {
evt.preventDefault()
if (value.indexOf(`gatsby-`) !== 0) return

installGatbyPlugin({
name: value,
})
}}
>
<InputField id={inputId}>
<Flex gap={2} flexDirection="column">
<InputFieldLabel>Install {props.for}:</InputFieldLabel>
<Flex gap={4} alignItems="center">
<InputFieldControl
placeholder={`gatsby-${props.for}-`}
disabled={fetching}
value={value}
onChange={(e): void => setValue(e.target.value)}
sx={{
width: `initial`,
}}
/>
<SecondaryButton
disabled={!value.trim()}
loading={fetching}
loadingLabel="Installing"
>
Install
</SecondaryButton>
</Flex>
</Flex>
</InputField>
</form>
)
}
import PluginSearchBar from "../components/plugin-search"

const SectionHeading: React.FC<HeadingProps> = props => (
<Heading as="h1" sx={{ fontWeight: `500`, fontSize: 5 }} {...props} />
Expand Down Expand Up @@ -181,7 +106,7 @@ const Index: React.FC<{}> = () => {
`,
})

if (fetching) return <p>Loading...</p>
if (fetching) return <Spinner />

if (error) return <p>Oops something went wrong.</p>

Expand All @@ -204,13 +129,15 @@ const Index: React.FC<{}> = () => {
))}
</ul>

<SectionHeading>Installed Plugins</SectionHeading>
<SectionHeading id="plugin-search-label">
Installed Plugins
</SectionHeading>
<Grid gap={6} columns={[1, 1, 1, 2, 3]}>
{data.allGatsbyPlugin.nodes.map(plugin => (
<PluginCard key={plugin.id} plugin={plugin} />
))}
</Grid>
<InstallInput for="plugin" />
<PluginSearchBar />
</Flex>
)
}
Expand Down
Loading