Skip to content

Commit

Permalink
Merge branch 'release/4.8.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Franck Cornu committed Nov 24, 2022
2 parents 9fd4a91 + 296ec76 commit 04f489e
Show file tree
Hide file tree
Showing 163 changed files with 48,623 additions and 9,942 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Extensibility release
name: Release Modern Search Extensibility package

on:
workflow_dispatch:
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/release-template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
**This solution includes only one `.sppkg` file:**
- `pnp-modern-search-parts-<version_number>.sppkg` (Mandatory).

> Extensions (i.e. custom web components, layouts, etc.) must be deployed separately. See [PnP Modern Search - Extensibility samples](https://github.com/microsoft-search/pnp-modern-search-extensibility-samples) for more information.
**Useful resources**

- [Official documentation](https://microsoft-search.github.io/pnp-modern-search/)

____
79 changes: 73 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
name: Release Modern Search WebParts SPFx package

on: workflow_dispatch
name: Release Modern Search Web Parts SPFx package

on:
workflow_dispatch:
inputs:
create_release:
default: true
description: 'Create GiHub release?'
push:
branches:
- main
- 'release/**'
- develop

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -12,7 +22,11 @@ jobs:
strategy:
matrix:
node-version: [14.x]


outputs:
majorMinorPatch: ${{ steps.setoutputs.outputs.majorMinorPatch }}
semver: ${{ steps.setoutputs.outputs.semver }}

steps:
- uses: actions/checkout@v3
with:
Expand All @@ -36,10 +50,63 @@ jobs:
- name: Determine Version
id: gitversion
uses: gittools/actions/gitversion/[email protected]

- name: Set outputs
id: setoutputs
run: |
echo "::set-output name=majorMinorPatch::$GITVERSION_MAJORMINORPATCH"
echo "::set-output name=semver::$GITVERSION_SEMVER"
- name: Build
- name: Build SPFx
run: |
pnpm install
gulp update-version --value $GITVERSION_MAJORMINORPATCH
gulp update-package-name --name pnp-modern-search-parts-$GITVERSION_SEMVER
gulp bundle --ship
gulp package-solution --ship
gulp package-solution --ship
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: pnp-modern-search-parts-${{ steps.gitversion.outputs.semVer }}
path: ${{ github.workspace }}/**/*.sppkg

release:
runs-on: ubuntu-latest
environment: production
if: ${{ github.ref_name == 'main' || startsWith(github.ref_name, 'release') || github.event.inputs.create_release }}
needs: build
steps:

- uses: actions/checkout@v3
with:
fetch-depth: 0

- uses: actions/download-artifact@v3
with:
name: pnp-modern-search-parts-${{ needs.build.outputs.semver }}

- name: Create GitHub release
uses: ncipollo/release-action@v1
with:
name: PnP Modern Search - ${{ needs.build.outputs.semVer }}
artifacts: ${{ github.workspace }}/**/*.sppkg
bodyFile: ".github/workflows/release-template.md"
draft: true
generateReleaseNotes: true
allowUpdates: true
replacesArtifacts: true
prerelease: ${{ startsWith(github.ref_name, 'release') }}
tag: ${{ needs.build.outputs.majorMinorPatch }}
commit: ${{ github.ref_name }}

- name: Setup python
uses: actions/setup-python@v2
with:
python-version: 3.x

- name: Deploy documentation
run: |
pip install markdown-include
pip install mkdocs-material==7.2.4
mkdocs gh-deploy --force
Binary file modified docs/assets/webparts/search-box/search_box_settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 119 additions & 0 deletions docs/extensibility/adaptivecards_customizations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Register Adaptive Cards Actions handlers customizations

If you want to render the search results using a custom Adaptive Card, you might also want to handle custom events upon actions happening in the Adaptive Cards instances.

To register a new Adaptive Cards Actions handler 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), implement the `invokeCardAction(action: any): void` method.

2. From within the method write your own implementation of any of the custom actions that you want to handle.

```typescript
public invokeCardAction(action: any): void {

// Process the action based on type
if (action.type == "Action.OpenUrl") {
window.open(action.url, "_blank");
} else if (action.type == "Action.Submit") {
// Process the action based on title
switch (action.title) {
case 'Click on item':
console.log(action.data);
break;
case 'Global click':
alert(action);
break;
default:
console.log('Action not supported!');
break;
}
}
}
```

3. In the JSON of the custom Adaptive Card, you can define the custom actions, like in the following code excerpt:

```json
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.3",
"body": [
{
"type": "TextBlock",
"text": "**${$root.data.totalItemsCount}** results",
"size": "Medium",
"wrap": true,
"$when": "${$root.properties.showResultsCount == true}"
},
{
"type": "Container",
"$data": "${data.items}",
"items": [
{
"type": "ColumnSet",
"id": "${hitId}",
"columns": [
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "<pnp-iconfile class='icon' data-extension='${if(empty($root.slots['FileType']),'',string(jPath($data, concat('.',$root.slots['FileType']))[0]))}'></pnp-iconfile>"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"wrap": true,
"text": "[${string(jPath($data, concat('.',$root.slots['Title']))[0])}](${string(jPath($data, concat('.',$root.slots['Path']))[0])})"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "ActionSet",
"actions": [
{
"type": "Action.Submit",
"title": "Click on item",
"style": "positive",
"data": {
"id": "123"
}
}
],
"spacing": "medium"
}
],
"width": "auto"
}
]
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Global click",
"data": {
"id": "456"
}
},
{
"type": "Action.OpenUrl",
"title": "Open URL",
"url": "https://pnp.github.io/"
}
]
}
```
74 changes: 74 additions & 0 deletions docs/extensibility/custom_data_sources.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Create a custom data source

Custom data sources can be added to a search results Web Part to get results from your custom source.

## Custom data source creation process

Custom data source creation process comes in two distinct steps:

1. [Create the data source logic](#create-the-component-logic-and-sub-components).
2. [Register the data source information for discovery](#register-component-information).

### Create the data source logic

* In your extensibility library project, create a new `CustomDataSource.ts` TypeScript file.
* Create an interface for your data source properties, typically the ones you want to persist in the Web Part property bag. Data source properties are isolated from the other general Web Part properties under the property `dataSourceProperties` in the property bag object.
```typescript
export interface ICustomDataSourceProperties {
possibleResults: string;
}
```

* Implement the `BaseDataSource` abstract class using your properties interface:
```typescript
export class CustomDataSource extends BaseDataSource<ICustomDataSourceProperties> {
...
}
```

* Implement your data source logic according to the available methods and properties.

### BaseDataSource - Methods

| Method | Description |
| --------- | ---------- |
| `onInit()`| The initialization method of your data source (ex: initialize your properties, etc.). You can perform asynchronous calls here. This method will be called when the data source is instantiated by the main Web Part.
| `getPropertyPaneGroupsConfiguration()` | Returns the property pane fields to display when your data source is selected. These are regular SPFx property fields and groups. Data source properties are isolated from the other general Web Part properties under the property `dataSourceProperties`. It means you must include that path in your property pane controls to 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.
| `getPagingBehavior()` | The method should return the desired paging behavior for the data source. Will be 'None' if not specified.
| `getFilterBehavior()` | The method should return the desired filter behavior for the data source. Will be 'Static' if not specified.
| `getAppliedFilters()` | If any, this method should return the list of filters (i.e data source fields) applied by the data source to filter results.
| `getItemCount()` | The method should return the total number of items. This information will be used to generate page numbers.
| `getTemplateSlots()` | The method should return the available template slots for this data source.
| `getSortableFields()` | The method should return the list of sortable fields for the data source if applicable


### BaseDataSource - Properties

| Property | Description |
| --------- | ---------- |
| `properties` | The Web Part properties in the property bag. Corresponds to the isolated `dataSourceProperties` property in the global property bag. You won't be able to access any other general properties of the Web Part.

### Register provider information

The next step is to provide information about your new data source. In the library main entry point (i.e. the class implementing the `IExtensibilityLibrary` in interface) return a new `IDataSourceDefinition` array in the `getCustomDataSources()` method using these properties:

| Property | Description |
| --------- | ---------- |
| `name` | The friendly name of your data source that will show up in the configuration panel.
| `iconName` | The name of an icon from Office UI Fabric/Fluent UI that will be shown in the data source options.
| `key` | An unique internal key for your data source.
| `serviceKey` | A service key used to instantiate your data source class. Builtin or custom data sources are instantiated dynamically using [SPFx service scopes](https://docs.microsoft.com/en-us/javascript/api/sp-core-library/servicescope?view=sp-typescript-latest).

```typescript
public getCustomDataSources(): IDataSourceDefinition[] {
return [
{
name: 'Custom Data Source',
iconName: 'Database',
key: 'CustomDataSource',
serviceKey: ServiceKey.create<IDataSource>('CustomDataSource', CustomDataSource)
}
];
}
```
74 changes: 74 additions & 0 deletions docs/extensibility/custom_query_modifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Create a custom query modifier

Custom query modifier can be added to a search result Web Part to modify search requests before they are sent to the server.

A query modifier supports:

- **Modification of query text and query template**: a query modifier can alter the query text and/or the query template.
- **Sorted modifications**: modifier can be sorted and are executed in order - but you can set a modifier to stop further modifications.

## Custom modifier creation process

Custom modifier creation process comes in two distinct steps:

1. [Create the modifier logic](#create-the-component-logic-and-sub-components).
2. [Register the modifier information for discovery](#register-component-information).

### Create the provider logic

* In your extensibility library project, create a new `CustomQueryModifier.ts` TypeScript file.
* Create an interface for your modifier properties, typically the ones you want to persist in the Web Part property bag. Modifier properties are isolated from the other general Web Part properties under the property `queryModifierProperties` in the property bag object.
```typescript
export interface ICustomQueryModifierProperties {
myProperty: string;
}
```

* Implement the `BaseQueryModifier` abstract class using your properties interface:
```typescript
export class CustomQueryModifier extends BaseQueryModifier<ICustomQueryModifierProperties> {
...
}
```

* Implement your query modifier logic according to the available methods and properties.

#### BaseQueryModifier - Methods

| Method | Description |
| --------- | ---------- |
| `onInit()`| The initialization method of your query modifier (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 initialize any consumed services if any.
| `modifyQuery()` | Method called to get a query modification when a search is requested(in paramter).
| `getPropertyPaneGroupsConfiguration()` | Returns the property pane fields to display when your query modifier is selected. These are regular SPFx property fields and groups. Query modifier properties are isolated from the other general Web Part properties under the property `queryModifierProperties`. 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.

#### BaseQueryModifier - Properties

| Property | Description |
| --------- | ---------- |
| `properties` | The Web Part properties in the property bag. Corresponds to the isolated `queryModifierProperties` property in the global property bag. You won't be able to access any other general properties of the Web Part.
| `endWhenSuccessfull` | Flag indicating if this should be the last query modification when the query was modified - can be switched in the query modifier list overview.

### Register provider information

The next step is to fill information about your new query modifier. In the library main entry point (i.e. the class implementing the `IExtensibilityLibrary` in interface) return a new `IQueryModifierDefinition` object in the `getCustomQueryModifiers()` method using these properties:

| Property | Description |
| --------- | ---------- |
| `name` | The friendly name of your query modifier that will show up in the configuration panel.
| `key` | An unique internal key for your data source.
| `description` | A meaningful description of your query modifier.
| `serviceKey` | A service key used to instanciate your query modifier class. Builtin or custom query modifiers 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 getCustomQueryModifiers(): IQueryModifierDefinition[] {
return [
{
name: 'Custom Query Modifier',
key: 'CustomQueryModifier',
description: 'A demo custom query modifier from the extensibility library',
serviceKey: ServiceKey.create<ISuggestionProvider>('MyCompany:CustomQueryModifier', CustomQueryModifier)
}
];
}
```
Loading

0 comments on commit 04f489e

Please sign in to comment.