-
Notifications
You must be signed in to change notification settings - Fork 342
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
452 changed files
with
58,273 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
SharePoint Patterns and Practices Community Search Solutions | ||
Copyright (c) Microsoft Corporation | ||
|
||
All rights reserved. | ||
|
||
MIT License | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# PnP Modern Search Solution | ||
|
||
This is a open source solution that helps you to build engaging search based solutions in the SharePoint modern experience. | ||
|
||
## Get Started | ||
|
||
Download the [latest release](https://github.com/microsoft-search/pnp-modern-search/releases/latest). | ||
|
||
More information to get started can be found documentation of this repository: [documentation](https://microsoft-search.github.io/pnp-modern-search). | ||
|
||
## Contributing | ||
|
||
This project welcomes contributions and suggestions. Most contributions require you to agree to a | ||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us | ||
the rights to use your contribution. For details, visit https://cla.microsoft.com. | ||
|
||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide | ||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions | ||
provided by the bot. You will only need to do this once across all repos using our CLA. | ||
|
||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). | ||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or | ||
contact [[email protected]](mailto:[email protected]) with any additional questions or comments. | ||
|
||
## "Sharing is Caring" | ||
|
||
## Disclaimer | ||
|
||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.** |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.center { | ||
display: block; | ||
margin-left: auto; | ||
margin-right: auto; | ||
} | ||
|
||
.logo { | ||
width: 150px; | ||
} | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+13.2 KB
docs/assets/webparts/search-results/connections/available_connections.png
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+21.2 KB
docs/assets/webparts/search-results/connections/input_text_dynamic.png
Oops, something went wrong.
Binary file added
BIN
+12.9 KB
docs/assets/webparts/search-results/connections/input_text_static.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+17.3 KB
docs/assets/webparts/search-results/layouts/details_list_hb_expr2.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+43.8 KB
docs/assets/webparts/search-results/layouts/result_types_template.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+68.4 KB
docs/assets/webparts/search-results/layouts/simple_list_thumbnail.png
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+16.4 KB
docs/assets/webparts/search-results/localization_crawled_property.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
Binary file added
BIN
+14.9 KB
docs/assets/webparts/search-results/search_results_wp_placeholder.png
Oops, something went wrong.
Oops, something went wrong.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Building the Documentation | ||
|
||
Building the documentation locally can help you visualize change you are making to the docs. What you see locally should be what you see online. | ||
|
||
## Building | ||
Documentation is built using MkDocs. You will need to latest version of Python (tested on version 3.7.1) and pip. If you're on the Windows operating system, make sure you have added Python to your [Path environment variable](https://docs.python.org/3/using/windows.html). | ||
|
||
When executing the pip module on Windows you can prefix it with **python -m**. | ||
For example: | ||
|
||
`python -m pip install mkdocs-material` | ||
|
||
- [Install MkDocs](https://www.mkdocs.org/#installation) | ||
- `pip install mkdocs` | ||
- Install the Material theme | ||
- `pip install mkdocs-material==4.6.3` | ||
- Serve it up | ||
- `mkdocs serve` | ||
- Open a browser to http://127.0.0.1:8000/ | ||
- Deploy | ||
- `mkdocs gh-deploy` from main branch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# Create a custom suggestions providers | ||
|
||
Custom suggestions providers can be added to a search box Web Part to get normalized keywords during search. | ||
|
||
!["Custom web component"](../assets/webparts/search_box/suggestions_demo.png){: .center} | ||
|
||
A suggestions provider supports: | ||
|
||
- **Zero term suggestions**: suggestions displayed when the search box get the initial focus and no term is provided. | ||
- **Suggestions based on a keywords**: suggestions matching specific keywords provided in the search box. | ||
|
||
## Custom suggestions provider creation process | ||
|
||
Suggestions provider creation process comes in two distinct steps: | ||
|
||
1. [Create the provider logic](#create-the-component-logic-and-sub-components). | ||
2. [Register the provider information for discovery](#register-component-information). | ||
|
||
### Create the provider logic | ||
|
||
* In your extensibility library project, create a new `MyProvider.ts` TypeScript file. | ||
* Create an interface for your provider properties, typically the ones you want to persist in the Web Part property bag. Providers properties are isolated from the other general Web Part properties under the property `providerProperties` in the property bag object. | ||
```typescript | ||
export interface ICustomSuggestionProviderProperties { | ||
myProperty: string; | ||
} | ||
``` | ||
|
||
* Implement the `BaseSuggestionProvider` abstract class using your properties interface: | ||
```typescript | ||
export class CustomSuggestionProvider extends BaseSuggestionProvider<ICustomSuggestionProviderProperties> { | ||
... | ||
} | ||
``` | ||
|
||
* Implement your provider logic according to the available methods and properties. | ||
|
||
#### BaseSuggestionProvider - Methods | ||
|
||
| Method | Description | | ||
| --------- | ---------- | | ||
| `onInit()`| The initialization method of your provider (ex: initialize your properties, etc.). You can perform asynchronous calls here. This method will be called when the provider is instanciated by the main Web Part. This is a good place to fetch any zero term suggestions if any. | ||
| `getSuggestions()` | Method called to retrieve suggestions when a keyword is entered (in paramter). | ||
| `getZeroTermSuggestions()` | Method called to retrieve the zero term suggestions (i.e. when the search box gets initial focus). | ||
| `getPropertyPaneGroupsConfiguration()` | Returns the property pane fields to display when your provider is selected. These are regular SPFx property fields and groups. PRovider properties are isolated from the other general Web Part properties under the property `providerProperties`. It means you must include that path in your property pane controls get the value persisted. Defining fields or groups is not mandatory for a provider. If you don't want to expose any option, just return an empty array. | ||
| `onPropertyUpdate()` | The method will be called when a property pane value is updated. The main Web Part in `Reactive` mode for property pane fields. | ||
|
||
#### BaseSuggestionProvider - Properties | ||
|
||
| Property | Description | | ||
| --------- | ---------- | | ||
| `properties` | The Web Part properties in the property bag. Corresponds to the isolated `providerProperties` property in the global property bag. You won't be able to access any other general properties of the Web Part. | ||
| `isZeroTermSuggestionsEnabled` | Flag indicating if the provider supports zero term suggestions or not. | ||
|
||
### Register provider information | ||
|
||
The next step is to fill information about your new suggestions provider. In the library main entry point (i.e. the class implementing the `IExtensibilityLibrary` in interface) return a new `ISuggestionProviderDefinition` object in the `getCustomSuggestionProviders()` method using these properties: | ||
|
||
| Property | Description | | ||
| --------- | ---------- | | ||
| `name` | The friendly name of your provider that will show up in the configuration panel. | ||
| `key` | An unique internal key for your data source. | ||
| `description` | A meaningful description of your provider. | ||
| `serviceKey` | A service key used to instanciate your provider class. Builtin or custom providers are instanciated dynamically using [SPFx service scopes](https://docs.microsoft.com/en-us/javascript/api/sp-core-library/servicescope?view=sp-typescript-latest). | ||
|
||
```typescript | ||
public getCustomSuggestionProviders(): ISuggestionProviderDefinition[] { | ||
return [ | ||
{ | ||
name: 'Custom Suggestions Provider', | ||
key: 'CustomSuggestionsProvider', | ||
description: 'A demo custom suggestions provider from the extensibility library', | ||
serviceKey: ServiceKey.create<ISuggestionProvider>('MyCompany:CustomSuggestionsProvider', CustomSuggestionProvider) | ||
} | ||
]; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Create a custom web component | ||
|
||
## What is a web component? | ||
|
||
A web component is a custom HTML element that can be used in your templates to implement complex behaviors. In the solution we used them here as *"wrappers"* for React components to be able to use them with Handlebars. More information about web components in general can be found [here](https://www.webcomponents.org/introduction). | ||
|
||
!["Custom web component"](../assets/extensibility/web_components/custom_web_component.png){: .center} | ||
|
||
By default, several components are available ([see the complete list](./web_components_list.md)). If these does not fit your requirement, you can still create your own. | ||
|
||
## Web component creation process | ||
|
||
Web component creation process comes in two distinct steps: | ||
|
||
1. [Create the component class and its React sub components](#create-the-component-logic-and-sub-components). | ||
2. [Register the component information for discovery](#register-component-information). | ||
|
||
|
||
### Create the component logic and sub components | ||
|
||
A web component is typically composed of these parts: | ||
|
||
* A web component class derived from the native `HTMLElement` class. | ||
* A main React component to be rendered inside the web component. | ||
|
||
To create new component: | ||
|
||
* In your extensibility library project, create a new `MyComponent.ts` JSX file. | ||
* Create a new class extending the abstract class `BaseWebComponent`. This class must have at least the `connectedCallback()` method from base interface `HTMLElement`. | ||
|
||
```typescript | ||
export class MyCustomComponentWebComponent extends BaseWebComponent { | ||
|
||
public constructor() { | ||
super(); | ||
} | ||
|
||
public async connectedCallback() { | ||
... | ||
} | ||
} | ||
``` | ||
|
||
* Create a new regular React component (in the same file or a separate file and as class or hook): | ||
|
||
```typescript | ||
export interface IObjectParam { | ||
myProperty: string; | ||
} | ||
|
||
export interface ICustomComponentProps { | ||
|
||
/** | ||
* A sample string param | ||
*/ | ||
myStringParam?: IObjectParam; | ||
|
||
/*** | ||
* A sample object param | ||
*/ | ||
myObjectParam?: string; | ||
} | ||
|
||
export interface ICustomComponenState { | ||
} | ||
|
||
export class CustomComponent extends React.Component<ICustomComponentProps, ICustomComponenState> { | ||
|
||
public render() { | ||
|
||
// Parse custom object | ||
const myObject: IObjectParam = this.props.myObjectParam; | ||
|
||
return <div>{this.props.myStringParam} {myObject.myProperty}</div>; | ||
} | ||
} | ||
``` | ||
|
||
In this solution, web components are considered **stateless**, meaning they will be entirely recreated when an attribute is changed (coming from the property pane). It means you can still use an internal state in your React components but not rely on the parent context (props) since it will be recreated every time by the Handlebars template if a property pane value is updated. The `componentDidMount()` method will be called every time in this case (not `componentDidUpdate()`). | ||
|
||
* In your web component class, render your React component: | ||
|
||
```typescript | ||
public async connectedCallback() { | ||
|
||
let props = this.resolveAttributes(); | ||
const customComponent = <CustomComponent {...props}/>; | ||
ReactDOM.render(customComponent, this); | ||
} | ||
``` | ||
|
||
The `resolveAttributes()` method will look at all `data-*` HTML attributes in your web component custom element node and return a corresponding key/value pair object with values **in their guessed type** that you can pass directly to your React component as props. By convention, web component attributes have to be passed using **camel case** to be tranformed into React component props. For instance: a `data-my-string-param` HTML attribute becomes `myStringParam` prop. | ||
|
||
Supported guessed types for attributes are **boolean**, **string**, **date** and **object**. All non supported types will be passed a **string**. HTML attributes must use the **data-** prefix to be retrieved correctly. | ||
|
||
To pass JSON objects, you can use the `JSONstringify` Handlebars helper. If valid JSON, they will be returned as **objects** by the `resolveAttributes()` method. | ||
|
||
**Example** | ||
```html | ||
<my-custom-component | ||
data-my-string-param="Default value" | ||
data-my-object-param="{{JSONstringify this 2}}" | ||
data-my-date-param="01/01/2020" | ||
data-my-boolean-param="true" | ||
> | ||
</my-custom-component> | ||
``` | ||
|
||
### Register component information | ||
|
||
The next step is to fill information about your new component. In the library main entry point (i.e. the class implementing the `IExtensibilityLibrary` in interface) return a new `IComponentDefinition` object in the `getCustomWebComponents()` method using these properties: | ||
|
||
|
||
| Property | Description | | ||
| --------- | ---------- | | ||
| `componentName` | The name for your component. This name will be used as the custom HTML element name (ex: `<my-custom-component>`). | ||
| `componentClass` | The web component class for that component. | ||
|
||
```typescript | ||
public getCustomWebComponents(): IComponentDefinition<any>[] { | ||
return [ | ||
{ | ||
componentName: 'my-custom-component', | ||
componentClass: MyCustomComponentWebComponent | ||
} | ||
]; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Register Handlebars customizations | ||
|
||
By default, builtin helpers and open-source [Handlebars helpers](https://github.com/helpers/handlebars-helpers) are available. If these don't fit your requirements, you can still create your own custom [helper](https://handlebarsjs.com/api-reference/helpers.html) or [partial](https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerpartial-name-partial) that you can use in your HTML templates or layout fields (ex: 'Cards' or 'Details List' layouts). | ||
|
||
> To avoid any conflict, each Web Part instance gets its own Handlebars isolated namespace (i.e. using `Handlebars.create()`) meaning registering customizations in the global Handlebars namespace **won't work** (ex: using `Handlebars.registerHelper()` directly). | ||
To register a new Handlebars customization for the targeted Web Part (i.e. the Web Part instances where the extensibility library is registered and enabled): | ||
|
||
1. In the library main entry point (i.e. the class implementing the `IExtensibilityLibrary` in interface), register your customization using the `registerHandlebarsCustomizations()` method. The `namespace` parameter corresponds to the targeted Web Part Handlebars isolated namespace: | ||
|
||
2. From here, use the Handlebars API to add your customizations to this specific namespace. They will be availabe in templates for registered Web Part instances: | ||
|
||
```typescript | ||
public registerHandlebarsCustomizations(namespace: typeof Handlebars) { | ||
|
||
// Register custom Handlebars helpers | ||
// Usage {{myHelper 'value'}} | ||
namespace.registerHelper('myHelper', (value: string) => { | ||
return new namespace.SafeString(value.toUpperCase()); | ||
}); | ||
} | ||
``` |
Oops, something went wrong.