Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-docs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid O'Regan <doregan@gitlab.com>2022-06-16 12:54:51 +0300
committerDavid O'Regan <doregan@gitlab.com>2022-06-16 12:54:51 +0300
commit8c014dc9f1c366207b57075005ced6e64351c9ec (patch)
tree05359e8de55d70f070d03bb1c9ddcfd89a486ee2 /content
parentbd3df1259d0ba5a1071e2eb4c5e135602383171a (diff)
parent700448adb96fe2a19bfb0c31b751ae99d188d9d7 (diff)
Merge branch 'instantsearch-vue' into 'main'
Use instantsearch-vue for the dedicated search page Closes #656 See merge request gitlab-org/gitlab-docs!2816
Diffstat (limited to 'content')
-rw-r--r--content/assets/stylesheets/instantsearch.scss184
-rw-r--r--content/frontend/search/components/search_page.vue77
-rw-r--r--content/frontend/search/docsearch.js8
-rw-r--r--content/frontend/search/index.js74
-rw-r--r--content/frontend/search/instantsearch.js35
-rw-r--r--content/frontend/search/search.js11
-rw-r--r--content/search/index.md24
7 files changed, 127 insertions, 286 deletions
diff --git a/content/assets/stylesheets/instantsearch.scss b/content/assets/stylesheets/instantsearch.scss
deleted file mode 100644
index f50c7f11..00000000
--- a/content/assets/stylesheets/instantsearch.scss
+++ /dev/null
@@ -1,184 +0,0 @@
----
-version: 15
----
-
-@import 'variables';
-
-// original CSS: https://github.com/algolia/examples/blob/master/instant-search/instantsearch.js/assets/style.css
-// original CSS customized and converted to SCSS with http://sebastianpontow.de/css2compass/
-
-//colors
-$color0: rgba(180, 162, 231, 0.1);
-$color1: rgba(180, 162, 231, 0.2);
-$color2: rgba(180, 162, 231, 0.1);
-$color3: rgba(79, 171, 225, 0.2);
-$color4: #eee;
-$color5: #ed5565;
-$color6: #999;
-$color7: #868686;
-$color8: #fff;
-$color9: #383838;
-$color10: rgb(117, 117, 117);
-$color11: transparent;
-// link-color: rgb(32, 139, 196);
-$color12: rgba(32, 139, 196, 0.2); //link color lighter
-
-
-/* stylelint-disable-next-line selector-class-pattern */
-.ais-SearchBox {
- width: 100%;
- max-width: 100% !important; // was 300px
-}
-
-.search-input {
- border-radius: 2px;
-}
-
-/* stylelint-disable-next-line selector-class-pattern */
-.ais-PoweredBy {
- font-family: $gl-regular-font;
- font-size: $body-font-size;
-
- svg {
- display: inline;
- }
-}
-
-.hit-content {
- border-top: 1px solid $color0;
- padding: 1rem 0.5rem;
- margin: 0;
- font-size: 13px;
- font-weight: 300;
- width: 100%; // was 81%
- position: relative;
- color: $color10;
- transition: 0.3s ease;
- word-wrap: break-word;
-
- &:hover {
- background-color: $color12;
-
- .hit-tag {
- color: $link-color;
- border-color: $color3;
- }
- }
-
- .lvl0 {
- color: $gds-black;
- }
-
- .lvl1 {
- font-size: 18px !important;
- }
-
- .lvl2 {
- font-size: 0.875rem;
- color: $color7;
- }
-
- .hit-name {
- font-weight: normal;
- margin-top: 0;
- }
-
- em {
- font-style: normal;
- background-color: $color3;
- }
-
- p {
- font-size: 13px;
- }
-
- .hit-description {
- margin: 1px 0 5px;
- }
-
- .hit-tag {
- display: block;
- position: absolute;
- padding: 3px;
- border: 1px solid $color0;
- border-top: 0;
- border-bottom-left-radius: 2px;
- border-bottom-right-radius: 2px;
- right: 0;
- top: 0;
- width: 70px;
- height: 25px;
- font-size: 11px;
- font-weight: 500;
- text-align: center;
- text-transform: uppercase;
- color: $color6;
- }
-
- .hit-text {
- font-size: inherit;
- color: $link-color;
- }
-
- @media all and (max-width: $bp-sm) {
- .hit-tag {
- width: 60px;
- height: 23px;
- font-size: 10px;
- }
-
- .lvl0 {
- padding-top: 5px;
- }
- }
-}
-
-#hits {
- /* stylelint-disable-next-line selector-list-comma-newline-after */
- > h1, h2, h3, h4, h5, h6 {
- border: 0;
- }
-}
-
-.algolia-docsearch-suggestion--highlight {
- background-color: $color3;
-}
-
-/* stylelint-disable selector-class-pattern */
-.ais-InfiniteHits {
- .ais-InfiniteHits-item {
- // https://github.com/algolia/instantsearch-specs/blob/v7.4.4/src/scss/themes/algolia.scss#L277-L305
- width: calc(100% - 1rem);
- border: 0;
- box-shadow: none;
- }
-}
-
-.ais-InfiniteHits-loadMore {
- display: block;
- width: 100%;
- margin: 1rem 0.5rem;
-
- &:focus {
- outline: none;
- }
-}
-
-.ais-Stats-text {
- color: $body-color;
-}
-
-.ais-RefinementList-item {
- display: inline-block;
- padding-right: 10px;
-}
-
-.ais-RefinementList-label {
- text-transform: uppercase;
- color: $link-color;
-}
-/* stylelint-enable selector-class-pattern */
-
-.search-results {
- min-height: 50vh;
-}
diff --git a/content/frontend/search/components/search_page.vue b/content/frontend/search/components/search_page.vue
new file mode 100644
index 00000000..621d2b9d
--- /dev/null
+++ b/content/frontend/search/components/search_page.vue
@@ -0,0 +1,77 @@
+<script>
+import algoliasearch from 'algoliasearch/lite';
+import 'instantsearch.css/themes/satellite-min.css';
+import { history as historyRouter } from 'instantsearch.js/es/lib/routers';
+import { singleIndex as singleIndexMapping } from 'instantsearch.js/es/lib/stateMappings';
+import { GlIcon } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlIcon,
+ },
+ props: {
+ docsVersion: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ searchClient: algoliasearch('3PNCFOU757', '89b85ffae982a7f1adeeed4a90bb0ab1'),
+ routing: {
+ router: historyRouter(),
+ stateMapping: singleIndexMapping('gitlab'),
+ },
+ };
+ },
+};
+</script>
+
+<template>
+ <ais-instant-search
+ :search-client="searchClient"
+ index-name="gitlab"
+ :routing="routing"
+ :stalled-search-delay="500"
+ class="gl-pb-8"
+ >
+ <h1 class="gl-mt-5!">Search</h1>
+ <ais-search-box
+ placeholder="Search GitLab Documentation"
+ show-loading-indicator
+ data-testid="docs-search"
+ />
+
+ <ais-state-results>
+ <template #default="{ results: { hits, query } }">
+ <div class="gl-display-flex gl-align-items-bottom gl-mb-6">
+ <ais-stats v-show="query.length > 0" class="gl-font-sm" />
+ <ais-powered-by
+ :class-names="{
+ 'ais-PoweredBy': 'gl-absolute gl-right-7 gl-mt-2',
+ 'ais-PoweredBy-link': 'no-attachment-icon gl-border-bottom-0!',
+ }"
+ />
+ </div>
+
+ <ais-infinite-hits v-if="query.length > 0 && hits.length > 0">
+ <template #item="{ item }">
+ <div>
+ <a :href="item.url" class="gl-font-lg">{{ item.hierarchy.lvl0 }}</a>
+ <p v-if="item.hierarchy.lvl2" class="gl-mt-2! gl-font-base!">
+ <gl-icon name="chevron-right" :size="12" /> {{ item.hierarchy.lvl2 }}
+ </p>
+ </div>
+ </template>
+ </ais-infinite-hits>
+
+ <div v-if="query.length > 0 && hits.length < 0">
+ No results found for <em>{{ query }}</em
+ >.
+ </div>
+ </template>
+ </ais-state-results>
+
+ <ais-configure :hits-per-page.camel="10" :facet-filters.camel="`version:` + docsVersion" />
+ </ais-instant-search>
+</template>
diff --git a/content/frontend/search/docsearch.js b/content/frontend/search/docsearch.js
index 0e12f398..e01ab696 100644
--- a/content/frontend/search/docsearch.js
+++ b/content/frontend/search/docsearch.js
@@ -1,11 +1,9 @@
import docsearch from '@docsearch/js';
import '@docsearch/css';
+import { getDocsVersion } from './search';
document.addEventListener('DOMContentLoaded', () => {
- let version = 'main';
- if (document.querySelector('meta[name="docsearch:version"]').content.length > 0) {
- version = document.querySelector('meta[name="docsearch:version"]').content;
- }
+ const docsVersion = getDocsVersion();
// eslint-disable-next-line no-undef
docsearch({
@@ -15,7 +13,7 @@ document.addEventListener('DOMContentLoaded', () => {
appId: '3PNCFOU757',
placeholder: 'Search the docs',
searchParameters: {
- facetFilters: [`version:${version}`],
+ facetFilters: [`version:${docsVersion}`],
},
resultsFooterComponent({ state }) {
return {
diff --git a/content/frontend/search/index.js b/content/frontend/search/index.js
deleted file mode 100644
index 1c658dc9..00000000
--- a/content/frontend/search/index.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import instantsearch from 'instantsearch.js';
-import { singleIndex } from 'instantsearch.js/es/lib/stateMappings';
-import {
- searchBox,
- refinementList,
- infiniteHits,
- stats,
- poweredBy,
- configure,
-} from 'instantsearch.js/es/widgets';
-import algoliasearch from 'algoliasearch';
-
-document.addEventListener('DOMContentLoaded', () => {
- const search = instantsearch({
- indexName: 'gitlab',
- searchClient: algoliasearch('3PNCFOU757', '89b85ffae982a7f1adeeed4a90bb0ab1'),
- algoliaOptions: {
- // Filter by tags as described in https://github.com/algolia/docsearch-configs/blob/master/configs/gitlab.json
- filters: 'tags:gitlab<score=3> OR tags:omnibus<score=2> OR tags:runner<score=1>',
- },
- routing: {
- stateMapping: singleIndex('gitlab'),
- },
- searchFunction: (helper) => {
- if (helper.state.query === '') {
- return;
- }
- helper.search();
- },
- });
-
- search.addWidgets([
- searchBox({
- container: '#searchbox',
- placeholder: 'Search GitLab Documentation',
- showReset: true,
- showLoadingIndicator: true,
- }),
-
- poweredBy({
- container: '#powered-by',
- }),
-
- refinementList({
- container: '#refinement-list',
- attribute: 'tags',
- sortBy: ['name:asc', 'isRefined'],
- templates: {
- header: 'Refine your search:',
- },
- }),
-
- infiniteHits({
- container: '#hits',
- templates: {
- item: document.getElementById('hit-template').innerHTML,
- empty: 'We didn\'t find any results for the search <em>"{{query}}"</em>',
- },
- escapeHits: true,
- showMoreLabel: 'Load more results...',
- }),
-
- stats({
- container: '#stats',
- }),
-
- configure({
- // Number of results shown in the search dropdown
- hitsPerPage: 10,
- }),
- ]);
-
- search.start();
-});
diff --git a/content/frontend/search/instantsearch.js b/content/frontend/search/instantsearch.js
new file mode 100644
index 00000000..64bd9f9a
--- /dev/null
+++ b/content/frontend/search/instantsearch.js
@@ -0,0 +1,35 @@
+import Vue from 'vue';
+import {
+ AisInstantSearch,
+ AisStateResults,
+ AisSearchBox,
+ AisStats,
+ AisPoweredBy,
+ AisInfiniteHits,
+ AisConfigure,
+} from 'vue-instantsearch';
+import SearchPage from './components/search_page.vue';
+import { getDocsVersion } from './search';
+
+Vue.component(AisInstantSearch.name, AisInstantSearch);
+Vue.component(AisSearchBox.name, AisSearchBox);
+Vue.component(AisStateResults.name, AisStateResults);
+Vue.component(AisStats.name, AisStats);
+Vue.component(AisPoweredBy.name, AisPoweredBy);
+Vue.component(AisInfiniteHits.name, AisInfiniteHits);
+Vue.component(AisConfigure.name, AisConfigure);
+
+const docsVersion = getDocsVersion();
+
+document.addEventListener('DOMContentLoaded', () => {
+ return new Vue({
+ el: '.js-instantsearch',
+ render(createElement) {
+ return createElement(SearchPage, {
+ props: {
+ docsVersion,
+ },
+ });
+ },
+ });
+});
diff --git a/content/frontend/search/search.js b/content/frontend/search/search.js
new file mode 100644
index 00000000..5ea8a87a
--- /dev/null
+++ b/content/frontend/search/search.js
@@ -0,0 +1,11 @@
+/**
+ * Functions used by both DocSearch and InstantSearch.
+ */
+
+export const getDocsVersion = () => {
+ let docsVersion = 'main';
+ if (document.querySelector('meta[name="docsearch:version"]').content.length > 0) {
+ docsVersion = document.querySelector('meta[name="docsearch:version"]').content;
+ }
+ return docsVersion;
+};
diff --git a/content/search/index.md b/content/search/index.md
index 8869da3f..a4d484db 100644
--- a/content/search/index.md
+++ b/content/search/index.md
@@ -1,26 +1,4 @@
---
-title: Search through GitLab Documentation
+title: Search GitLab Docs
layout: instantsearch
-feedback: nil
---
-<header>
- <div id="searchbox"></div>
- <div id="powered-by"></div>
-</header>
-<main class="search-results">
- <div id="stats"></div>
- <div id="refinement-list"></div>
- <div id="hits"></div>
-
- <script type="text/html" id="hit-template">
- <a href="{{ url }}" class="hit">
- <div class="hit-content">
- <h3 class="hit-name lvl0">{{{_highlightResult.hierarchy.lvl0.value}}}</h3>
- <h4 class="hit-description lvl1">{{{_highlightResult.hierarchy.lvl1.value}}}</h4>
- <h5 class="hit-description lvl2">{{{_highlightResult.hierarchy.lvl2.value}}}</h5>
- <div class="hit-text">{{{_highlightResult.content.value}}}</div>
- <div class="hit-tag">{{ tags }}</div>
- </div>
- </a>
- </script>
-</main>