From 91e1d886ec5988fa9084872821cc34c72744fbe1 Mon Sep 17 00:00:00 2001 From: Mikael Svenson Date: Tue, 6 Feb 2024 10:40:44 +0100 Subject: [PATCH 01/50] Remove version in the text, prompting dev to check the current version. --- docs/extensibility/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/extensibility/index.md b/docs/extensibility/index.md index 474c9cea..70d11b76 100644 --- a/docs/extensibility/index.md +++ b/docs/extensibility/index.md @@ -29,7 +29,7 @@ For your project to be a valid extensibility library, you must have the followin - You library **manifest ID** must be registered in the Web Part where you want to use the extension. !!! important "SPFx version" - The SPFx library project must use the same SPFx version as the main solution (currently `1.15.2`). Owherwise you may face issues at build time. See [GitHub issue #1893](https://github.com/microsoft-search/pnp-modern-search/issues/1893) + The SPFx library project must use the same SPFx version as the main solution (check source code for current version). Owherwise you may face issues at build time. See [GitHub issue #1893](https://github.com/microsoft-search/pnp-modern-search/issues/1893) ### Supported extensions From d416535e876e4420b312d9357ca52de506ff7701 Mon Sep 17 00:00:00 2001 From: Hilton Giesenow Date: Thu, 8 Feb 2024 12:48:55 +0200 Subject: [PATCH 02/50] Update templating.md --- docs/extensibility/templating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/extensibility/templating.md b/docs/extensibility/templating.md index 5ea71fe5..a7331e99 100644 --- a/docs/extensibility/templating.md +++ b/docs/extensibility/templating.md @@ -64,7 +64,7 @@ The following custom helpers are available in addition to the [handlebars-helper | `{{getUrlParameter }}` | Return the query parameter value from a URL. Omitting the optional url parameter uses the current browser URL. | `{{getUrlParameter "k"}}` return the value of the `k` query parameter from the browser URL.

`{{getUrlParameter "k" "https://foo?k=test"}}` return the value of the `k` query parameter from the provided URL. -> Need any other helper? Let us know [here](https://github.com/aequos-solutions/modern-search-results/issues)! +> Need any other helper? Let us know [here](https://github.com/microsoft-search/pnp-modern-search/issues)! ### Using builtin web components From 904db751a9cbfe5c39a150e43ca318f6118b7d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Bl=C3=BCml?= Date: Wed, 14 Feb 2024 07:48:51 +0100 Subject: [PATCH 03/50] fixed some typos and texts in German localization files --- search-parts/src/loc/de-de.js | 34 +++++++++---------- .../src/webparts/searchBox/loc/de-de.js | 18 +++++----- .../src/webparts/searchFilters/loc/de-de.js | 10 +++--- .../src/webparts/searchResults/loc/de-de.js | 22 ++++++------ .../src/webparts/searchVerticals/loc/de-de.js | 6 ++-- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/search-parts/src/loc/de-de.js b/search-parts/src/loc/de-de.js index 4f8764f3..dcad38b9 100644 --- a/search-parts/src/loc/de-de.js +++ b/search-parts/src/loc/de-de.js @@ -1,4 +1,4 @@ -define([], function() { +define([], function () { return { Tokens: { SelectTokenLabel: "Wähle ein Token...", @@ -14,7 +14,7 @@ define([], function() { Custom: { CustomTokensGroupName: "Benutzerdefinerter Wert", CustomValuePlaceholder: "Wert eingeben...", - InvalidtokenFormatErrorMessage: "Bitte gebe den Token im unterstützten Format ein: {' und '}'. (z.B.: {Today})" + InvalidtokenFormatErrorMessage: "Bitte geben Sie den Token im unterstützten Format ein: {' und '}'. (z.B.: {Today})" }, Date: { DateTokensGroupName: "Datums Token", @@ -54,14 +54,14 @@ define([], function() { }, Extensibility: { InvalidDataSourceInstance: "Die ausgewählte Datenquelle '{0}' implementiert die abstrakte Klasse 'BaseDataSource' nicht korrekt. Es fehlen einige Methoden.", - DataSourceDefinitionNotFound: "Die benutzerdefinierte Datenquelle mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Web Part registriert ist.", - LayoutDefinitionNotFound: "Das benutzerdefinierte Layout mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für das App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", + DataSourceDefinitionNotFound: "Die benutzerdefinierte Datenquelle mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", + LayoutDefinitionNotFound: "Das benutzerdefinierte Layout mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", InvalidLayoutInstance: "Das ausgewählte Layout '{0}' implementiert die abstrakte Klasse 'BaseLayout' nicht korrekt. Es fehlen einige Methoden.", DefaultExtensibilityLibraryName: "Standard-Erweiterungsbibliothek", InvalidProviderInstance: "Der ausgewählte Vorschlagsprovider '{0}' implementiert die abstrakte Klasse 'BaseSuggestionProvider' nicht korrekt. Es fehlen einige Methoden.", ProviderDefinitionNotFound: "Der benutzerdefinierte Vorschlagsprovider mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", - QueryModifierDefinitionNotFound: "Der benutzerdefinierte Benutzer-Anfragen-Modifizierer mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", - InvalidQueryModifierInstance: "Der ausgewählte Benutzer-Anfragen-Modifizierer '{0}' implementiert die abstrakte Klasse 'BaseQueryModifier' nicht korrekt. Es fehlen einige Methoden.", + QueryModifierDefinitionNotFound: "Der benutzerdefinierte Abfragemodifikator mit dem Schlüssel '{0}' wurde nicht gefunden. Stellen Sie sicher, dass die Lösung korrekt für den App-Katalog bereitgestellt und die Manifest-ID für dieses Webpart registriert ist.", + InvalidQueryModifierInstance: "Der ausgewählte Abfragemodifikator '{0}' implementiert die abstrakte Klasse 'BaseQueryModifier' nicht korrekt. Es fehlen einige Methoden.", }, DateFromLabel: "Von", DateTolabel: "Bis", @@ -96,7 +96,7 @@ define([], function() { NoResultsSearchMessage: "Keine Ergebnisse gefunden", SearchPlaceholder: "Suche einen Wert..." }, - CurrentVerticalNotSelectedMessage: "Das derzeit ausgewählte Vertikal passt nicht zu den zu diesem Web Part ({0}) zugeordneten Vertikalen. Es wird im Anzeige Modus als leer angezeigt." + CurrentVerticalNotSelectedMessage: "Das derzeit ausgewählte Vertikal passt nicht zu den zu diesem Web Part ({0}) zugeordneten Vertikalen. Es wird im Anzeige Modus als leer angezeigt." }, DataSources: { SharePointSearch: { @@ -109,8 +109,8 @@ define([], function() { QueryTemplateFieldDescription: "Die Vorlage für die Suchanfrage. Sie können auch {} verwenden, um eine dynamische Abfrage zu erstellen.", ResultSourceIdLabel: "ID der Ergebnisquelle / Scope|Name", ResultSourceIdDescription: "Verwenden Sie eine standardmäßige SharePoint-Ergebnisquellen-ID, geben Sie Ihren eigenen GUID-Wert ein oder den SCOPE und NAMEN der Quelle getrennt durch '|' (z.B.: SPSite|News). Erlaubte Scopes sind [SPSiteSubscription, SPSite, SPWeb]. Drücken Sie zum Speichern die [Eingabetaste].", - InvalidResultSourceIdMessage: "Der angegebene Wert ist keine gültige GUID oder nicht als SCOPE|NAME formattiert.", - EnableQueryRulesLabel: "Abfrageregeln aktivieren", + InvalidResultSourceIdMessage: "Der angegebene Wert ist keine gültige GUID oder nicht in der Form 'SCOPE|NAME' formatiert.", + EnableQueryRulesLabel: "Abfrageregeln aktivieren", RefinementFilters: "Verfeinerungsfilter", RefinementFiltersDescription: "Initiale Verfeinerungsfilter, die auf die Abfrage angewendet werden sollen. Diese werden nicht in den ausgewählten Filtern angezeigt. Verwenden Sie für String-Ausdrücke doppelte Anführungszeichen (\") anstelle von einfachen Anführungszeichen (').", EnableLocalizationLabel: "Lokalisierung einschalten", @@ -122,10 +122,10 @@ define([], function() { SelectedPropertiesFieldDescription: "Gibt die Eigenschaften an, die aus den Suchergebnissen abgerufen werden sollen.", SelectedPropertiesPlaceholderLabel: "Eigenschaften auswählen", HitHighlightedPropertiesFieldLabel: "Hervorgehobene Eigenschaften", - HitHighlightedPropertiesFieldDescription: "Liste der verwalteten Eigenschaften zum hervorheben (i.e. Department,UserName).", + HitHighlightedPropertiesFieldDescription: "Liste der verwalteten Eigenschaften zum Hervorheben (i.e. Department,UserName).", TermNotFound: "(Begriff mit ID '{0}' nicht gefunden)", ApplyQueryTemplateBtnText: "Übernehmen", - EnableAudienceTargetingTglLabel: "Zielgruppen Adressierung aktivieren", + EnableAudienceTargetingTglLabel: "Zielgruppenadressierung aktivieren", TrimDuplicates: "Duplikate kürzen", CollapseSpecificationLabel: "Spezifikation einklappen" }, @@ -152,7 +152,7 @@ define([], function() { TrimDuplicates: "Duplikate kürzen", CollapseProperties: { EditCollapsePropertiesLabel: "Bearbeiten Sie die Minimierungseinstellungen", - CollapsePropertiesDescription: "Angiv indstillingerne for sammenbrud for søgeresultaterne. Du kan enten vælge et felt fra rullelisten (kun hvis datakildedataene allerede er hentet) eller indtaste din egen tilpassede værdi (tryk på 'Enter' for at gemme din indtastning)", + CollapsePropertiesDescription: "Geben Sie die Minimierungseinstellungen für die Suchergebnisse an. Sie können entweder ein Feld aus der Dropdown-Liste auswählen (nur wenn die Daten der Datenquelle bereits abgerufen wurden) oder einen eigenen Wert eingeben (drücken Sie 'Enter', um Ihre Eingabe zu speichern).", CollapsePropertiesPropertyPaneFieldLabel: "Minimierungseinstellungen", CollapseLimitFieldLabel: "Grenze", CollapsePropertiesFieldColumnPlaceholder: "Nach Feld reduzieren" @@ -164,7 +164,7 @@ define([], function() { SortListDescription: "Geben Sie die initiale Sortierreihenfolge für die Suchergebnisse an. Sie können entweder ein Feld aus der Dropdown-Liste auswählen (nur wenn die Daten der Datenquelle bereits abgerufen wurden) oder einen eigenen Wert eingeben (drücken Sie 'Enter', um Ihre Eingabe zu speichern).", SortDirectionAscendingLabel: "Aufsteigend", SortDirectionDescendingLabel: "Absteigend", - SortErrorMessage: "Ungültige Sucheigenschaft (Prüfen Sie, ob die verwaltete Eigenschaft sortierbar ist).", + SortErrorMessage: "Ungültige Sucheigenschaft (prüfen Sie, ob die verwaltete Eigenschaft sortierbar ist).", SortPanelSortFieldLabel: "Nach Feld sortieren", SortPanelSortFieldAria: "Sortiere nach", SortPanelSortFieldPlaceHolder: "Sortiere nach", @@ -349,14 +349,14 @@ define([], function() { OrOperator: "OR", AndOperator: "AND", ComboBoxPlaceHolder: "Wert auswählen", - UseAndOperatorValues: "Benutze ein AND Operator zwischen den Werten.", - UseOrOperatorValues: "Benutze ein OR Operator zwischen den Werten.", - UseValuesOperators: "Wähle einen Operator der zwischen den Filter Werten angewandt werden soll." + UseAndOperatorValues: "Benutze einen AND Operator zwischen den Werten.", + UseOrOperatorValues: "Benutze einen OR Operator zwischen den Werten.", + UseValuesOperators: "Wähle einen Operator, der zwischen den Filterwerten angewandt werden soll." }, SuggestionProviders: { SharePointStatic: { ProviderName: "SharePoint Statische Suchvorschläge", - ProviderDescription: "Abrufen von statischen benutzerdefinierten SharePoint-Suchvorschlägen" + ProviderDescription: "Abrufen von statischen, benutzerdefinierten SharePoint-Suchvorschlägen" } } } diff --git a/search-parts/src/webparts/searchBox/loc/de-de.js b/search-parts/src/webparts/searchBox/loc/de-de.js index bc03ad74..969b1b09 100644 --- a/search-parts/src/webparts/searchBox/loc/de-de.js +++ b/search-parts/src/webparts/searchBox/loc/de-de.js @@ -1,4 +1,4 @@ -define([], function() { +define([], function () { return { General: { DynamicPropertyDefinition: "Such query" @@ -8,32 +8,32 @@ define([], function() { GroupName: "Suchbox Einstellungen", PlaceholderTextLabel: "Platzhalter zum Anzeigen in der Suchbox", SearchInNewPageLabel: "Query an eine neue Seite senden", - ReQueryOnClearLabel: "Abfrage bei Löschen zurücksetzen", + ReQueryOnClearLabel: "Abfrage beim Löschen zurücksetzen", PageUrlLabel: "Seiten URL", UrlErrorMessage: "Bitte eine valide URL angeben.", QueryPathBehaviorLabel: "Methode", QueryInputTransformationLabel: "Query Eingabe Transformations-Vorlage", UrlFragmentQueryPathBehavior: "URL Fragment", - QueryStringQueryPathBehavior: "Query string Parameter", + QueryStringQueryPathBehavior: "Query-String Parameter", QueryStringParameterName: "Parameter Name", QueryParameterNotEmpty: "Bitte einen Wert für den Parameter angeben." }, AvailableConnectionsGroup: { GroupName: "Verfügbare Verbindungen", - UseDynamicDataSourceLabel: "Benutze eine dynamsche Daten Quelle als Standard Eingabe.", + UseDynamicDataSourceLabel: "Benutze eine dynamische Datenquelle als Standard-Eingabe.", QueryKeywordsPropertyLabel: "" }, QuerySuggestionsGroup: { GroupName: "Query Vorschläge", - EnableQuerySuggestions: "Aktiviere Query Vorschläge", - EditSuggestionProvidersLabel: "Configuriere mögliche Provider", + EnableQuerySuggestions: "Aktiviere Abfrage Vorschläge", + EditSuggestionProvidersLabel: "Konfiguriere mögliche Vorschlags Provider", SuggestionProvidersLabel: "Vorschlags Provider", - SuggestionProvidersDescription: "Aktiviere oder deaktivierte individuelle Vorschlag Provider.", + SuggestionProvidersDescription: "Aktiviere oder deaktivierte individuelle Vorschlags Provider.", EnabledPropertyLabel: "Aktiviert", ProviderNamePropertyLabel: "Name", ProviderDescriptionPropertyLabel: "Beschreibung", DefaultSuggestionGroupName: "Empfohlen", - NumberOfSuggestionsToShow: "Anzahl der Vorschläge pro Gruppe die angezeigt werden sollen." + NumberOfSuggestionsToShow: "Anzahl der Vorschläge pro Gruppe, die angezeigt werden sollen." }, InformationPage: { Extensibility: { @@ -41,7 +41,7 @@ define([], function() { PanelDescription: "Füge hinzu / entferne die IDs der benutzerdefinierten Erweiterungsbibliotheken. Ein Anzeigename kann hinzugefügt werden und ob die Bibliothek beim Start geladen werden soll. Nur benutzerdefinierte Vorschlags Provider werden hier geladen.", } }, - + }, SearchBox: { DefaultPlaceholder: "Suchbegriffe eingeben...", diff --git a/search-parts/src/webparts/searchFilters/loc/de-de.js b/search-parts/src/webparts/searchFilters/loc/de-de.js index 0973c98f..ca237e6c 100644 --- a/search-parts/src/webparts/searchFilters/loc/de-de.js +++ b/search-parts/src/webparts/searchFilters/loc/de-de.js @@ -15,12 +15,12 @@ define([], function() { UseDataResultsWebPartLabel: "Verbinde einen Suchergebnis Webpart.", UseDataResultsFromComponentsLabel: "Benutze Daten von diesen Webparts", UseDataResultsFromComponentsDescription: "Wenn mehr als ein Webpart verbunden ist, dann werden die Filter Werte und die Anzahl für ähnliche Filter Namen zusammengeführt.", - LinkToVerticalLabel: "Zeige Filter nur an wenn folgende Vertikale ausgewählt sind", - LinkToVerticalLabelHoverMessage: "Diese Filter werden nur angezeigt wenn das ausgewählte Vertikal mit einem der für diesen Webpart konfigurierten übereinstimmt. Ansonsten bleibt das Webpart im Anzeigemodus blank (kein Rand)." + LinkToVerticalLabel: "Zeige Filter nur an, wenn folgende Vertikale ausgewählt sind", + LinkToVerticalLabelHoverMessage: "Diese Filter werden nur angezeigt, wenn das ausgewählte Vertikal mit einem der für dieses Webpart konfigurierten übereinstimmt. Ansonsten bleibt das Webpart im Anzeigemodus leer (kein Rand)." }, FiltersSettingsPage: { SettingsGroupName: "Filter Einstellungen", - FilterOperator: "Operator zum Nutzen zwischen den Filtern" + FilterOperator: "Operator zwischen den Filtern" }, DataFilterCollection: { SelectFilterComboBoxLabel: "Wähle ein Feld", @@ -31,10 +31,10 @@ define([], function() { FilterExpandByDefault: "Standardmäßig erweitert", FilterType: "Filter Typ", FilterTypeRefiner: "Diese Filter Vorlage agiert als ein Verfeinerer und erhält/sendet verfügbare/ausgewählte Werte von/zu einer verbundenen Datenquelle.", - FilterTypeStaticFilter: "Diese Filter Vorlage agiert als ein statischer Filter udn sendet nur willkürlich ausgewählte Werte zu der verbundenen Datenquelle. Einkommende Filter Werte werden nicht beachtet.", + FilterTypeStaticFilter: "Diese Filter Vorlage agiert als ein statischer Filter und sendet nur willkürlich ausgewählte Werte zu der verbundenen Datenquelle. Einkommende Filter Werte werden nicht beachtet.", CustomizeFiltersBtnLabel: "Bearbeiten", CustomizeFiltersHeader: "Filter bearbeiten", - CustomizeFiltersDescription: "Such Filter durch hinzufügen / entfernen von Zeilen konfigurieren. Für die Filter können Felder von den Datenquellen Ergebnissen oder statische Werte selektiert werden.", + CustomizeFiltersDescription: "Filter durch Hinzufügen/Entfernen von Zeilen konfigurieren. Für die Filter können Felder von den Datenquellen-Ergebnissen oder statische Werte selektiert werden.", CustomizeFiltersFieldLabel: "Filter anpassen", ShowCount: "Zeige Anzahl", Operator: "Operator zwichen Werten", diff --git a/search-parts/src/webparts/searchResults/loc/de-de.js b/search-parts/src/webparts/searchResults/loc/de-de.js index a6b9d9f3..69c61c37 100644 --- a/search-parts/src/webparts/searchResults/loc/de-de.js +++ b/search-parts/src/webparts/searchResults/loc/de-de.js @@ -1,4 +1,4 @@ -define([], function() { +define([], function () { return { General: { PlaceHolder: { @@ -8,20 +8,20 @@ define([], function() { ConfigureBtnLabel: "Konfigurieren" }, WebPartDefaultTitle: "Suchergebnis Webpart", - ShowBlankEditInfoMessage: "Keine Ergebnisse für diese Abfrage. Dieser Webpart bleibt im Anzeigemodus entsprechend den Parametern leer.", - CurrentVerticalNotSelectedMessage: "Die aktuell ausgewählte Vertikale stimmt nicht mit der für diesen Webpart zugeordneten überein. Sie bleibt im Anzeigemodus leer." + ShowBlankEditInfoMessage: "Keine Ergebnisse für diese Abfrage. Dieses Webpart bleibt im Anzeigemodus entsprechend den Parametern leer.", + CurrentVerticalNotSelectedMessage: "Die aktuell ausgewählte Vertikale stimmt nicht mit der für dieses Webpart zugeordneten überein. Sie bleibt im Anzeigemodus leer." }, PropertyPane: { DataSourcePage: { DataSourceConnectionGroupName: "Verfügbare Datenquellen", PagingOptionsGroupName: "Paging-Optionen", - ItemsCountPerPageFieldName: "Anzahl der items pro Seite", + ItemsCountPerPageFieldName: "Anzahl der Treffer pro Seite", PagingRangeFieldName: "Anzahl der anzuzeigenden Seiten im Bereich", ShowPagingFieldName: "Paging anzeigen", HidePageNumbersFieldName: "Verstecke Seitenzahlen", HideNavigationFieldName: "Navigationsknopf verstecken (Seite vor/zurück)", HideFirstLastPagesFieldName: "Anfang/Ende Navigationsknöpfe verstecken", - HideDisabledFieldName: "Navigationsknöpfe verstecken (vor, zurück, Anfang, Ende) wenn sie deaktiviert sind.", + HideDisabledFieldName: "Navigationsknöpfe verstecken (vor, zurück, Anfang, Ende), wenn sie deaktiviert sind", TemplateSlots: { GroupName: "Layout Slots", ConfigureSlotsLabel: "Layout Slots für diese Datenquelle bearbeiten", @@ -44,8 +44,8 @@ define([], function() { DialogButtonLabel: "Ergebnisvorlage bearbeiten", DialogTitle: "Ergebnisvorlage bearbeiten", ShowSelectedFilters: "Ausgewählte Filter anzeigen", - ShowBlankIfNoResult: "Webpart verstecken wenn es nichts zum Anzeigen gibt.", - ShowResultsCount: "Anzahl der Ergebniss anzeigen", + ShowBlankIfNoResult: "Webpart verstecken, wenn es nichts zum Anzeigen gibt", + ShowResultsCount: "Anzahl der Ergebnisse anzeigen", HandlebarsRenderTypeLabel: "Handlebars/HTML", HandlebarsRenderTypeDesc: "Wählen Sie Layouts basierend auf HTML, CSS und Handlebars aus", AdaptiveCardsRenderTypeLabel: "Adaptive Cards", @@ -81,7 +81,7 @@ define([], function() { AsTokensSelectionMode: "Ausgewählte Werte als Token verarbeiten (manueller Modus)", AsDataFiltersSelectionMode: "Ausgewählte Werte als Filter (Standard Modus)", AsDataFiltersDescription: "In diesem Modus werden die ausgewählten Werte als reguläre Suchverfeinerungen an die Datenquelle gesendet. In diesem Fall muss die gewählte Zieleigenschaft im Suchschema verfeinerbar sein.", - AsTokensDescription: "In diesem Modus werden die ausgewählten Werte manuell über Token und den verfügbare Methoden verwendet. Beispiel anhand einer SharePoint-Suchabfragevorlage: {?Title:{filters.<destination_field_name>.valueAsText}}", + AsTokensDescription: "In diesem Modus werden die ausgewählten Werte manuell über Token und die verfügbaren Methoden verwendet. Beispiel anhand einer SharePoint-Suchabfragevorlage: {?Title:{filters.<destination_field_name>.valueAsText}}", FilterValuesOperator: "Der logische Operator, der zwischen den ausgewählten Werten verwendet werden soll", FieldToConsumeLabel: "Zu konsumierendes Quellenfeld", FieldToConsumeDescription: "Diesen Feldwert für ausgewählte Items verwenden" @@ -96,7 +96,7 @@ define([], function() { UseFiltersFromComponentLabel: "Filter dieser Komponente verwenden", UseDynamicFilteringsWebPartLabel: "Mit einem Suchergebnis Webpart verbinden", UseDataResultsFromComponentsLabel: "Daten von diesem Webpart verwenden", - UseDataResultsFromComponentsDescription: "Daten von ausgewählten Items in diesen Webparts verwenden", + UseDataResultsFromComponentsDescription: "Daten von ausgewählten Items in diesen Webparts verwenden", UseSearchVerticalsWebPartLabel: "Mit einem Vertikal Webpart verbinden", UseSearchVerticalsFromComponentLabel: "Benutze Vertikale von dieser Komponente", LinkToVerticalLabel: "Daten nur anzeigen, wenn das folgene Vertikal ausgewählt ist", @@ -116,7 +116,7 @@ define([], function() { }, InformationPage: { Extensibility: { - PanelHeader: "Erweiterungsbibliotheken die beim Start geladen werden konfigurieren ", + PanelHeader: "Erweiterungsbibliotheken, die beim Start geladen werden, konfigurieren", PanelDescription: "Hier können Sie die IDs Ihrer benutzerdefinierten Erweiterungsbibliotheken hinzufügen/entfernen. Sie können einen Anzeigenamen angeben und entscheiden, ob die Bibliothek beim Starten geladen werden soll oder nicht. Nur benutzerdefinierte Datenquellen, Layouts, Webkomponenten und Handlebars-Helfer werden hier geladen.", } }, @@ -127,7 +127,7 @@ define([], function() { EnabledPropertyLabel: "Aktiviert", ModifierNamePropertyLabel: "Name", ModifierDescriptionPropertyLabel: "Beschreibung", - EndWhenSuccessfullPropertyLabel:"Bei Erfolg beenden" + EndWhenSuccessfullPropertyLabel: "Bei Erfolg beenden" } } } diff --git a/search-parts/src/webparts/searchVerticals/loc/de-de.js b/search-parts/src/webparts/searchVerticals/loc/de-de.js index 01fd1163..1dfc3da6 100644 --- a/search-parts/src/webparts/searchVerticals/loc/de-de.js +++ b/search-parts/src/webparts/searchVerticals/loc/de-de.js @@ -5,7 +5,7 @@ define([], function() { PlaceHolder: { EditLabel: "Bearbeiten", IconText: "Such Vertikal Webpart von @pnp", - Description: "Erlaubt die Anzeige von Daten als Vertikale (Silos). Dieses Webpart soll zu bestehenden 'Suchergebnis' Webparts auf der Seite verbunden werden.", + Description: "Erlaubt die Anzeige von Daten als Vertikale (Sparten). Dieses Webpart kann mit bestehenden 'Suchergebnis' Webparts auf der Seite verbunden werden.", ConfigureBtnLabel: "Konfigurieren" } }, @@ -14,9 +14,9 @@ define([], function() { Verticals: { PropertyLabel: "Such Vertikal", PanelHeader: "Konfiguriere Such Vertikale", - PanelDescription: "Füge ein neues Vertikal hinzu, welches den Benutzern ermöglicht in einem vorgegebenen Bereich oder Datenquelle zu suchen. Um es zu nutzen muss dieses Webpart mit einem oder mehreren 'Suchergebnis' Webparts über dessen Eigenschaften verbunden werden. ", + PanelDescription: "Füge ein neues Vertikal hinzu, welches den Benutzern ermöglicht, in einem vorgegebenen Bereich oder Datenquelle zu suchen. Um es zu nutzen, muss dieses Webpart mit einem oder mehreren 'Suchergebnis' Webparts über dessen Eigenschaften verbunden werden. ", ButtonLabel: "Konfiguriere Vertikale", - DefaultVerticalQueryStringParamLabel: "Query string Parameter zur automatischen Auswahl eines Vertikals.", + DefaultVerticalQueryStringParamLabel: "Query-String Parameter zur automatischen Auswahl eines Vertikals.", DefaultVerticalQueryStringParamDescription: "Der Tab Name oder die derzeitige URL (wenn das Tab ein Hyperlink ist) werden dabei verglichen.", Fields: { TabName: "Tab Name", From 6c1eef15931f6c72ad709ff4df8281865c758f08 Mon Sep 17 00:00:00 2001 From: Kasper Larsen Date: Wed, 14 Feb 2024 08:13:19 +0100 Subject: [PATCH 04/50] Update Danish localization strings --- .../src/webparts/searchFilters/loc/da-dk.js | 8 +++---- .../src/webparts/searchResults/loc/da-dk.js | 24 ++++++++++++------- .../src/webparts/searchVerticals/loc/da-dk.js | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/search-parts/src/webparts/searchFilters/loc/da-dk.js b/search-parts/src/webparts/searchFilters/loc/da-dk.js index 7aeebdc1..63239e9a 100644 --- a/search-parts/src/webparts/searchFilters/loc/da-dk.js +++ b/search-parts/src/webparts/searchFilters/loc/da-dk.js @@ -28,7 +28,7 @@ define([], function() { FilterDisplayName: "Visningsnavn", FilterMaxBuckets: "Antal værdier", FilterTemplate: "Skabelon", - FilterExpandByDefault: "Udvid som default", + FilterExpandByDefault: "Udvid som standard", FilterType: "Filtertype", FilterTypeRefiner: "Denne skabelon til filtre agerer som en refiner og modtager/sender tilgængelige/valgte værdier fra/til the forbundne datakilde.", FilterTypeStaticFilter: "Denne skabelon til filtre agerer som et statisk filter og sender kun vilkårligt udvalgte værdier til den forbundne datakilde. Indgående filterværdier bliver ikke taget i betragtning.", @@ -42,7 +42,7 @@ define([], function() { OROperator: "ELLER", IsMulti: "Multiværdier", Templates: { - CheckBoxTemplate: "Check box", + CheckBoxTemplate: "Checkboks", DateRangeTemplate: "Datointerval", ComboBoxTemplate: "Combo-boks", DateIntervalTemplate: "Datointerval", @@ -51,7 +51,7 @@ define([], function() { SortBy: "Sortér værdier efter", SortDirection: "Sortér efter retning", SortByName: "Efter navn", - SortByCount: "Efter optælling", + SortByCount: "Efter antal", SortAscending: "Stigende", SortDescending: "Faldende" }, @@ -60,7 +60,7 @@ define([], function() { LayoutTemplateOptionsGroupName: "Layout-muligheder", TemplateUrlFieldLabel: "Anvend en ekstern URL til skabelonen", TemplateUrlPlaceholder: "https://myfile.html", - ErrorTemplateExtension: "Skabelonen skal være en valid .txt, .htm eller .html fil", + ErrorTemplateExtension: "Skabelonen skal være en valid .htm eller .html fil", ErrorTemplateResolve: "Ude af stand til at vise den specifikke skabelon. Fejloplysninger: '{0}'", FiltersTemplateFieldLabel: "Redigér skabelon til filtre", FiltersTemplatePanelHeader: "Redigér skabelon til filtre" diff --git a/search-parts/src/webparts/searchResults/loc/da-dk.js b/search-parts/src/webparts/searchResults/loc/da-dk.js index 77a4b19b..64a29eb3 100644 --- a/search-parts/src/webparts/searchResults/loc/da-dk.js +++ b/search-parts/src/webparts/searchResults/loc/da-dk.js @@ -15,7 +15,7 @@ define([], function() { DataSourcePage: { DataSourceConnectionGroupName: "Tilgængelige datakilder", PagingOptionsGroupName: "Sidevisninger", - ItemsCountPerPageFieldName: "Antal items per side", + ItemsCountPerPageFieldName: "Antal elementer per side", PagingRangeFieldName: "Antal sider der skal vises i rækkefølge", ShowPagingFieldName: "Vis sideantal", HidePageNumbersFieldName: "Skjul sidenumre", @@ -39,7 +39,7 @@ define([], function() { CommonOptionsGroupName: "Almindelig", TemplateUrlFieldLabel: "Anvend en URL fra en ekstern skabelon", TemplateUrlPlaceholder: "https://myfile.html", - ErrorTemplateExtension: "Skabelonen skal være en valid .txt, .htm or .html fil", + ErrorTemplateExtension: "Skabelonen skal være en valid .htm or .html fil", ErrorTemplateResolve: "Kan ikke læse the specificerede skabelon. Fejlbeskrivelse: '{0}'", DialogButtonLabel: "Redigér resultatsskabelonen", DialogTitle: "Redigér resultatsskabelonen", @@ -47,7 +47,7 @@ define([], function() { ShowBlankIfNoResult: "Skjul denne webpart, hvis der ikke er noget at vise.", ShowResultsCount: "Vis antallet af resultater", HandlebarsRenderTypeLabel: "Handlebars/HTML", - HandlebarsRenderTypeDesc: "Vælg layout baseret på HTML, CSS og styr", + HandlebarsRenderTypeDesc: "Vælg layout baseret på HTML, CSS og Handlebars", AdaptiveCardsRenderTypeLabel: "Adaptive Cards", AdaptiveCardsRenderTypeDesc: "Vælg layout baseret på JSON adaptive kort", Handlebars: { @@ -62,13 +62,13 @@ define([], function() { CondtionOperatorValue: "Operatør", ExternalUrlLabel: "Ekstern skabelon-URL", EqualOperator: "Er lig med", - NotEqualOperator: "Er ikke lige med", + NotEqualOperator: "Er ikke lig med", ContainsOperator: "Indeholder", StartsWithOperator: "Starter med", NotNullOperator: "Er ikke nul", - GreaterOrEqualOperator: "Større eller lig", + GreaterOrEqualOperator: "Større eller lig med", GreaterThanOperator: "Større end", - LessOrEqualOperator: "Mindre eller lig", + LessOrEqualOperator: "Mindre eller lig med", LessThanOperator: "Mindre end", CancelButtonText: "Annuller", DialogButtonText: "Redigér skabelon", @@ -83,8 +83,13 @@ define([], function() { AsDataFiltersDescription: "I denne tilstand sendes valgte værdier til datakilden som almindelige filtre", AsTokensDescription: "I denne tilstand bruges de valgte værdier manuelt gennem tokens og tilgængelige metoder. Eksempel med SharePoint søgeforespørgselsskabelon: {?Title:{filters.<destination_field_name>.valueAsText}}", FilterValuesOperator: "Den logiske operator, der skal bruges mellem valgte værdier", +<<<<<<< HEAD FieldToConsumeLabel: "Kildefelt til at forbruge", + FieldToConsumeDescription: "Brug denne feltværdi til at skabe forbindelse til den anden datakilde", +======= + FieldToConsumeLabel: "Kildefelt til at anvende", FieldToConsumeDescription: "Brug denne feltværdi til udvalgte varer", +>>>>>>> 4b7c7e1f08e290b3d1232a7b8e787c8c5cac06e4 }, AdaptiveCards: { HostConfigFieldLabel: "Værtskonfiguration" @@ -109,7 +114,7 @@ define([], function() { InputQueryTextStaticValue: "Statisk værdi", InputQueryTextDynamicValue: "Dynamisk værdi", SearchQueryTextUseDefaultQuery: "Brug en standard værdi", - SearchQueryTextDefaultValue: "Standard værdi", + SearchQueryTextDefaultValue: "Standardværdi", SourceDestinationFieldLabel: "Navn på destinationsfelt", SourceDestinationFieldDescription: "Destinationsfelt til brug i denne webdel for at matche de valgte værdier", AvailableFieldValuesFromResults: "Felt, der indeholder filterværdien" @@ -118,7 +123,10 @@ define([], function() { Extensibility: { PanelHeader: "Konfigurér extensibility-biblioteker så de indlæser ved opstart.", PanelDescription: "Tilføj/Fjern ID på dit extensibility-bibliotek her. Du kan specificere et visningsnavn og beslutte, om biblioteket skal indlæses eller ej ved opstart. Kun brugerdefinerede datakilder, layouts, web-komponenter og Handlebars-hjælpere vil blive loadet her.", - } + }, + EnableTelemetryLabel: "PnP telemetri", + EnableTelemetryOn: "Slå telemetri til", + EnableTelemetryOff: "Slå telemetri fra" }, CustomQueryModifier: { EditQueryModifiersLabel: "Konfigurere tilgængelige brugerdefinerede forespørgselsmodifikatorer", diff --git a/search-parts/src/webparts/searchVerticals/loc/da-dk.js b/search-parts/src/webparts/searchVerticals/loc/da-dk.js index 6ecfbe44..28c62561 100644 --- a/search-parts/src/webparts/searchVerticals/loc/da-dk.js +++ b/search-parts/src/webparts/searchVerticals/loc/da-dk.js @@ -5,7 +5,7 @@ define([], function() { PlaceHolder: { EditLabel: "Redigere", IconText: "Search Verticals Web Part af @pnp", - Description: "Giver mulighed for at gennemse data som vertikaler (dvs. siloer). Denne webdel er beregnet til at blive forbundet med 'Søgeresultater' webdele på siden.", + Description: "Giver mulighed for at gennemse data som vertikaler/faner (dvs. siloer). Denne webdel er beregnet til at blive forbundet med 'Søgeresultater' webdele på siden.", ConfigureBtnLabel: "Konfigurer" } }, From 1bcb87e8d707896a74ae22bcc52d539b82b1b776 Mon Sep 17 00:00:00 2001 From: Kasper Larsen Date: Mon, 19 Feb 2024 08:36:43 +0100 Subject: [PATCH 05/50] Update bug report and index.md templates + new Q&A page --- .github/ISSUE_TEMPLATE/bug_report.md | 7 +++++ docs/Q&A.md | 45 +++++++++++++++++++++++++++ docs/assets/LCP.png | Bin 0 -> 18824 bytes docs/index.md | 9 +++++- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 docs/Q&A.md create mode 100644 docs/assets/LCP.png diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3fb9aa9a..a8d4219e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,6 +7,8 @@ assignees: '' --- + + ### Check existing issues before logging new ones If you are not using the latest version, triage your issue with the latest version before logging as we won't provide patches to older versions. @@ -16,6 +18,11 @@ If you are not using the latest version, triage your issue with the latest versi __Remove the above section before submitting, and removal of the below template will result in the issue being closed.__ +### Follow the template below or we will have to delete this request!! +We can assist a lot faster if you provide the following information: + + + **Version used** Ex: 4.8 diff --git a/docs/Q&A.md b/docs/Q&A.md new file mode 100644 index 00000000..0e556110 --- /dev/null +++ b/docs/Q&A.md @@ -0,0 +1,45 @@ + + +**Q: In version 4.10.1 the LPC (Live Person Card) hover option became available as an option for the People Layout. What is the difference between LCP and Persona card? ** + +![LCP option](/assets/LCP.png "LCP option in the People Layout") + + + + + +**A**: The Live Person Card does not require any additional Graph Permissions. The LPC can be customized to show additional fields from Entra ID, but not the same way as the pnp-people or mgt-person. However it will always show equal to any other people card shown in Microsoft 365.See https://learn.microsoft.com/en-us/graph/add-properties-profilecard. + + ---------------------- + +**Q: Is the deprecation of SharePoint-Add-in's affecting PnP Modern Search?** + +**A**: No, as the project is built using the SharePoint Framework, not the deprecated add-in model. + +----------------------- + +**Q: Is the PnP Modern Search package certified by a 3rd party in order to ensure compliance with GDPR or similar requirements? ** + +**A**: No, it is up to you to review the source code in order to ensure compliance with any relevant requirements. The web parts do not store, process or log any data, thus GDPR is not directly relevant. Any privacy concern of data is up to how data is stored and protected at the source level, e.g. SharePoint. + + ----------------------- + +**Q: Are the PnP Modern Search web parts logging data to a local or remote receiver? ** + +**A**: No, the PnP Modern Search web parts are not logging data to any receiver, not even telemetry data. + + ----------------------- + +**Q: What is the ID or Name of the PnP Modern Search App Registration in Azure AD/Entra? ** + +**A**: There isn’t an App Registration nor Enterprise application as PnP Modern Search does not rely on an application entry. The solution uses FedAuth cookies from SharePoint when calling the SharePoint Search API, and uses the “SharePoint Online Client Extensibility” app registrations when calling Graph API’s. + +The solution does elevate any permissions when calling the API’s as permissions are all of the type Delegated Permissions, meaning that the permissions are bound to the current user, not the PnP Modern Search solution. + + ----------------------- + +**Q: I am concerned about what will happen if the project is abandoned. Will Microsoft take over the project? ** + +**A**: It is hard to predict the future, but a vast number of companies are using the PnP Modern Search web parts in their solutions. The solution is hosted on GitHub owned by the Microsoft Search team. Most likely these companies will either clone the project and make a commercial version or will provide the manpower needed to keep the project in maintenance mode. + +----------------------- \ No newline at end of file diff --git a/docs/assets/LCP.png b/docs/assets/LCP.png new file mode 100644 index 0000000000000000000000000000000000000000..4e2cc9bb75d314a8d1b0cd27257f72cbc489b1e0 GIT binary patch literal 18824 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 literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 87b83da7..f4551b67 100644 --- a/docs/index.md +++ b/docs/index.md @@ -86,9 +86,15 @@ Also, to help us to resolve your issue, you can include screenshots or error mes - Errors displayed in the SharePoint console (pressing CTRL+F12) ## Issues, questions, feedback? - For any issue, question or feedback, please the [official GitHub repository](https://github.com/microsoft-search/pnp-modern-search/issues). We will be happy to help you! +## Q&A +We have a list of frequently asked questions available [here](q&a). If you have a question, it might be already answered there. + + + + + ## About @@ -110,3 +116,4 @@ Here is the list of main contributors of the PnP Modern Search (all versions inc - Paolo Pialorsi (PiaSys.com) - [@PaoloPia](https://twitter.com/paolopia) - Patrik Hellgren (SherparsGroupAB) - [@PatrikHellgren](https://twitter.com/patrikhellgren) - Erfan Darroudi [@edarroudi](https://github.com/edarroudi) +- Kasper Larsen (Fellowmind) - [@kasperlarsen](https://twitter.com/kasperbolarsen) From 7b80de607bd8680bf3ce987f30e93363be480b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Bl=C3=BCml?= Date: Tue, 20 Feb 2024 09:25:28 +0100 Subject: [PATCH 06/50] Added missing localization-strings for German language --- search-parts/src/loc/de-de.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/search-parts/src/loc/de-de.js b/search-parts/src/loc/de-de.js index dcad38b9..217f6ffa 100644 --- a/search-parts/src/loc/de-de.js +++ b/search-parts/src/loc/de-de.js @@ -160,8 +160,8 @@ define([], function () { }, SearchCommon: { Sort: { - SortPropertyPaneFieldLabel: "Sortierreihenfolge", - SortListDescription: "Geben Sie die initiale Sortierreihenfolge für die Suchergebnisse an. Sie können entweder ein Feld aus der Dropdown-Liste auswählen (nur wenn die Daten der Datenquelle bereits abgerufen wurden) oder einen eigenen Wert eingeben (drücken Sie 'Enter', um Ihre Eingabe zu speichern).", + SortPropertyPaneFieldLabel: "Sortierung", + SortListDescription: "Geben Sie die Sortierung der Suchergebnisse an. Sie können entweder ein Feld aus der Dropdown-Liste auswählen (nur wenn die Daten der Datenquelle bereits abgerufen wurden) oder einen eigenen Wert eingeben (drücken Sie 'Enter', um Ihre Eingabe zu speichern).", SortDirectionAscendingLabel: "Aufsteigend", SortDirectionDescendingLabel: "Absteigend", SortErrorMessage: "Ungültige Sucheigenschaft (prüfen Sie, ob die verwaltete Eigenschaft sortierbar ist).", @@ -170,8 +170,11 @@ define([], function () { SortPanelSortFieldPlaceHolder: "Sortiere nach", SortPanelSortDirectionLabel: "Sortierrichtung", SortDirectionColumnLabel: "Richtung", - SortFieldColumnLabel: "Feld Name", - EditSortLabel: "Sortierreihenfolge bearbeiten", + SortFieldColumnLabel: "Feldname", + SortFieldDefaultSortLabel: "Standardmäßig sortieren", + SortFieldFriendlyNameLabel: "Anzeigename des Sortierfelds", + SortFieldUserSortLabel: "Sortierung durch Benutzer", + EditSortLabel: "Sortierung bearbeiten", SortInvalidSortableFieldMessage: "Diese Eigenschaft ist nicht sortierbar", SortFieldColumnPlaceholder: "Wähle Feld..." } @@ -217,7 +220,8 @@ define([], function () { ManageDetailsListColumnDescription: "Hinzufügen, Aktualisieren oder Entfernen von Spalten für das Layout der Detailliste. Sie können entweder Eigenschaftswerte in der Liste direkt und ohne Transformation verwenden oder einen Handlebar-Ausdruck im Wertefeld einsetzen. HTML wird ebenfalls für alle Felder unterstützt.", ManageDetailsListColumnLabel: "Spalten verwalten", ValueColumnLabel: "Spalten Wert", - ValueSortingColumnLabel: "Sortierung von Spaltenwerten", + ValueSortingColumnLabel: "Sortierfeld auswählen...", + ValueSortingColumnNoFieldsLabel: "Keine Sortierfelder verfügbar", DisplayNameColumnLabel: "Spaltenanzeigename", FileExtensionFieldLabel: "Zu verwendendes Feld für die Dateierweiterung", GroupByFieldLabel: "Gruppierung nach Feld", @@ -276,13 +280,15 @@ define([], function () { PersonaSizeExtraSmall: "Extra klein", PersonaSizeSmall: "Klein", PersonaSizeRegular: "Regulär", - PersonaSizeLarge: "Gross", - PersonaSizeExtraLarge: "Extra gross", + PersonaSizeLarge: "Groß", + PersonaSizeExtraLarge: "Extra groß", ShowInitialsToggleLabel: "Initialen anzeigen, wenn kein Bild vorhanden", SupportHTMLColumnLabel: "HTML erlauben", ResetFieldsBtnLabel: "Felder auf Standardwerte zurücksetzen", ShowPersonaCardOnHover: "Persona-Karte bei Hover anzeigen", - ShowPersonaCardOnHoverCalloutMsg: "Diese Funktion verwendet Microsoft Graph, um Informationen über den Benutzer anzuzeigen, und benötigt die folgenden API-Berechtigungen in Ihrem Mandanten, um zu funktionieren: ['User.Read','People.Read','Contacts.Read','User.Read.All'].", + ShowPersonaCardOnHoverCalloutMsg: "Diese Funktion verwendet Microsoft Graph, um Informationen über den Benutzer anzuzeigen. Sie benötigt die folgenden API-Berechtigungen in Ihrem Mandanten, um zu funktionieren: ['User.Read','People.Read','Contacts.Read','User.Read.All'].", + ShowPersonaCardOnHoverNative: "Persona-Karte bei Hover anzeigen (LPC)", + ShowPersonaCardOnHoverCalloutMsgNative: "Diese Funktion verwendet die Standard-Komponente von SharePoint, um die LivePersona-Karte anzuzeigen. Beachten Sie den Disclaimer unter https://pnp.github.io/sp-dev-fx-controls-react/controls/LivePersona/.", Fields: { ImageUrl: "Bild URL", PrimaryText: "Primärer Text", From 747fecb38136c6f4dd155482d6efa056ced9e6d0 Mon Sep 17 00:00:00 2001 From: Patrik Hellgren Date: Tue, 20 Feb 2024 15:16:25 +0100 Subject: [PATCH 07/50] Fix for text styling in sections with different background color --- .../src/components/CollapsibleContentComponent.tsx | 11 ++++++++--- .../components/filters/FilterCheckBoxComponent.tsx | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/search-parts/src/components/CollapsibleContentComponent.tsx b/search-parts/src/components/CollapsibleContentComponent.tsx index ac276975..4943d6ce 100644 --- a/search-parts/src/components/CollapsibleContentComponent.tsx +++ b/search-parts/src/components/CollapsibleContentComponent.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { BaseWebComponent } from '@pnp/modern-search-extensibility'; import * as ReactDOM from 'react-dom'; -import { IGroup, IGroupDividerProps, Icon, Text, GroupedList } from '@fluentui/react'; +import { IGroup, IGroupDividerProps, Icon, Text, GroupedList, ITextProps, ITextTokens, ITextSlots, IStyleFunctionOrObject, ITextStyles } from '@fluentui/react'; import { IReadonlyTheme } from '@microsoft/sp-component-base'; import styles from './CollapsibleContentComponent.module.scss'; import 'core-js/features/dom-collections'; @@ -126,7 +126,12 @@ export class CollapsibleContentComponent extends React.Component = { + root: { + color: textColor + } + }; return (
- {props.group.name} + {props.group.name}
{props.group.isCollapsed ? diff --git a/search-parts/src/components/filters/FilterCheckBoxComponent.tsx b/search-parts/src/components/filters/FilterCheckBoxComponent.tsx index ee026861..6bec8b20 100644 --- a/search-parts/src/components/filters/FilterCheckBoxComponent.tsx +++ b/search-parts/src/components/filters/FilterCheckBoxComponent.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { BaseWebComponent, IDataFilterInfo, IDataFilterValueInfo, ExtensibilityConstants } from '@pnp/modern-search-extensibility'; import * as ReactDOM from 'react-dom'; -import { Checkbox, ChoiceGroup, IChoiceGroupOption, ITheme, Text } from '@fluentui/react'; +import { Checkbox, ChoiceGroup, IChoiceGroupOption, IStyleFunctionOrObject, ITextProps, ITextStyles, ITheme, Text } from '@fluentui/react'; import { IReadonlyTheme } from '@microsoft/sp-component-base'; export interface IFilterCheckBoxProps { @@ -72,6 +72,11 @@ export class FilterCheckBoxComponent extends React.Component = { + root: { + color: textColor + } + }; if (this.props.isMulti) { renderInput = { - return {props.label}; + return {props.label}; }} />; } else { From ea32093446feb6fee848474e9d9b032d91c899f3 Mon Sep 17 00:00:00 2001 From: Patrik Hellgren Date: Tue, 20 Feb 2024 15:26:16 +0100 Subject: [PATCH 08/50] Remove unused imports --- search-parts/src/components/CollapsibleContentComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search-parts/src/components/CollapsibleContentComponent.tsx b/search-parts/src/components/CollapsibleContentComponent.tsx index 4943d6ce..2583bb2f 100644 --- a/search-parts/src/components/CollapsibleContentComponent.tsx +++ b/search-parts/src/components/CollapsibleContentComponent.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { BaseWebComponent } from '@pnp/modern-search-extensibility'; import * as ReactDOM from 'react-dom'; -import { IGroup, IGroupDividerProps, Icon, Text, GroupedList, ITextProps, ITextTokens, ITextSlots, IStyleFunctionOrObject, ITextStyles } from '@fluentui/react'; +import { IGroup, IGroupDividerProps, Icon, Text, GroupedList, ITextProps, IStyleFunctionOrObject, ITextStyles } from '@fluentui/react'; import { IReadonlyTheme } from '@microsoft/sp-component-base'; import styles from './CollapsibleContentComponent.module.scss'; import 'core-js/features/dom-collections'; From c46c3755f47772e99c59c9125a65172dfcf03ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20Bl=C3=BCml?= Date: Wed, 21 Feb 2024 11:12:35 +0100 Subject: [PATCH 09/50] Add "Show presence"-option to People-Layout --- docs/extensibility/web_components_list.md | 25 ++-- docs/usage/search-results/layouts/people.md | 1 + .../src/components/PersonaComponent.tsx | 117 +++++++++++++++++- .../layouts/results/people/PeopleLayout.ts | 14 +++ .../src/layouts/results/people/people.html | 6 +- search-parts/src/loc/commonStrings.d.ts | 2 + search-parts/src/loc/da-dk.js | 2 + search-parts/src/loc/de-de.js | 2 + search-parts/src/loc/en-us.js | 2 + search-parts/src/loc/es-es.js | 2 + search-parts/src/loc/fi-fi.js | 2 + search-parts/src/loc/fr-fr.js | 2 + search-parts/src/loc/nb-no.js | 2 + search-parts/src/loc/nl-nl.js | 2 + search-parts/src/loc/pl-pl.js | 2 + search-parts/src/loc/pt-br.js | 2 + search-parts/src/loc/sv-SE.js | 2 + 17 files changed, 174 insertions(+), 13 deletions(-) diff --git a/docs/extensibility/web_components_list.md b/docs/extensibility/web_components_list.md index 9b502d81..7b1801f9 100644 --- a/docs/extensibility/web_components_list.md +++ b/docs/extensibility/web_components_list.md @@ -2,15 +2,16 @@ Here are the list of all **reusable** web components you can use to customize your templates. -- [<pnp-iconfile>](#ltpnp-iconfilegt) -- [<pnp-documentcard>](#ltpnp-documentcardgt) -- [<pnp-filepreview>](#ltpnp-filepreviewgt) -- [<pnp-icon>](#ltpnp-icongt) -- [<pnp-panel>](#ltpnp-panelgt) -- [<pnp-collapsible>](#ltpnp-collapsiblegt) -- [<pnp-persona>](#ltpnp-personagt) -- [<pnp-img>](#ltpnp-imggt) -- [<pnp-breadcrumb>](#ltpnp-breadcrumbgt) +- [Builtin web components](#builtin-web-components) + - [``](#pnp-iconfile) + - [``](#pnp-documentcard) + - [``](#pnp-filepreview) + - [``](#pnp-icon) + - [``](#pnp-panel) + - [``](#pnp-collapsible) + - [``](#pnp-persona) + - [``](#pnp-img) + - [``](#pnp-breadcrumb) > All other web components you will see in builtin layout templates are considered **internal** and are not supported for custom use. @@ -191,7 +192,9 @@ Here are the list of all **reusable** web components you can use to customize yo data-tertiary-text="" data-optional-text="514 928 0000" data-persona-size="" - data-native-lpc=true > + data-native-lpc=true + data-show-presence=true + data-user-object-id="[GUID]"> ``` @@ -204,6 +207,8 @@ Here are the list of all **reusable** web components you can use to customize yo |**data-optional-text**|The optional text to display. |**data-persona-size**|The size of the persona **item** to display (no only the picture). Valid values are
  • tiny = 0
  • extraExtraSmall = 1
  • extraSmall = 2
  • small = 3
  • regular = 4
  • large = 5
  • extraLarge = 6
|**data-native-lpc**|Enable SharePoint native Live Persona Card on hover. +|**data-show-presence**|Show the user's presence-information. +|**data-user-object-id**|The person's Entra ID Object-ID (a GUID normally provided by the default-slot "PersonQuery" which is mapped to managed property "AADObjectID") ## `` - **Description**: Display an image with support for fallback behavior. diff --git a/docs/usage/search-results/layouts/people.md b/docs/usage/search-results/layouts/people.md index 7a351e3b..deb2f9e1 100644 --- a/docs/usage/search-results/layouts/people.md +++ b/docs/usage/search-results/layouts/people.md @@ -9,6 +9,7 @@ The 'people' layout display a list of persons with additional information. Typic | **Manage people fields** | Allows you to define you own values for people placeholder fields.

[!["Manage people fields"](../../../assets/webparts/search-results/layouts/manage_people_fields.png)](../../../assets/webparts/search-results/layouts/manage_people_fields.png)

As a field value, you can choose either a field property value (from the list or as free text) and without any transformation or use an Handlebars expression by clicking on the checkbox next to it. In this case, all helpers from the main template are available. Also, if the field doesn't have the **'Allow HTML'** indication flag enabled, it means the value will be always interpreted as text, regardless if you set an HTML value. Otherwise, your value will be interpreted as HTML for those fields (ex: '_Primary text_' placeholder field). For HTML fields you can use the special variable `@root.theme` to use theme colors (ex: `@root.theme.palette.themePrimary`) or `@root.slots.` to access slot value. If you don't set a value for those fields (i.e an empty value), they won't appear in the UI.
| **Show persona card on hover (LPC)** | If enabled, show a person card on hover for the curren item using the native SharePoint implementation. | **Show persona card on hover** | If enabled, show a person card on hover for the current item.

[!["Persona card hover"](../../../assets/webparts/search-results/layouts/persona_card_hover.png)](../../../assets/webparts/search-results/layouts/persona_card_hover.png)

This feature uses Microsoft Graph and [Microsoft Graph Toolkit](https://docs.microsoft.com/en-us/graph/toolkit/components/person) to display information about the user and needs the following API permissions in your tenant to work:
  • User.Read
  • People.Read
  • Contacts.Read
  • User.Read.All
**If these permissions are not set, the card won't appear**. You can use [PnP Office 365 CLI](https://pnp.github.io/office365-cli/cmd/spo/serviceprincipal/serviceprincipal-grant-add/) to add correct permissions for this feature:

`$m365 spo serviceprincipal grant add --resource '' --scope 'user_impersonation'`. Refer to the section below about [persona hover card customization](#persona-hover-card). +| **Show presence** |

If enabled, the person's presence-information will be displayed in the bottom right corner of the user's profile picture.

This feature uses Microsoft Graph and needs the API permission 'Presence.Read.All' in your tenant to work. | **Component size** | The size of the person item (not only the picture). The more the size is and the more information will be displayed for each item and vice versa. #### Persona hover card diff --git a/search-parts/src/components/PersonaComponent.tsx b/search-parts/src/components/PersonaComponent.tsx index 68e57421..ab2d36eb 100644 --- a/search-parts/src/components/PersonaComponent.tsx +++ b/search-parts/src/components/PersonaComponent.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Persona, IPersonaProps, IPersonaSharedProps, getInitials, Icon, ITheme } from '@fluentui/react'; +import { Persona, IPersonaProps, IPersonaSharedProps, getInitials, Icon, ITheme, PersonaPresence } from '@fluentui/react'; import { TemplateService } from "../services/templateService/TemplateService"; import * as ReactDOM from 'react-dom'; import { IReadonlyTheme } from '@microsoft/sp-component-base'; @@ -10,8 +10,11 @@ import { UrlHelper } from '../helpers/UrlHelper'; import { isEmpty } from '@microsoft/sp-lodash-subset'; import { DomPurifyHelper } from '../helpers/DomPurifyHelper'; import { IComponentFieldsConfiguration } from '../models/common/IComponentFieldsConfiguration'; -import { ServiceScope, ServiceKey } from '@microsoft/sp-core-library'; +import { ServiceScope, ServiceKey, Log } from '@microsoft/sp-core-library'; import { LivePersona } from "@pnp/spfx-controls-react/lib/LivePersona"; +import { MSGraphClientFactory } from '@microsoft/sp-http'; + +const LogSource = "PersonaComponent"; export interface IPersonaComponentProps { @@ -81,9 +84,26 @@ export interface IPersonaComponentProps { * Enable native LPC from SharePoint */ nativeLpc?: boolean; + + /** + * Show presence information? + */ + showPresence?: boolean; + + /** + * The person's Entra ID Object-ID (usually passed via default-slot "PersonQuery") + */ + userObjectId?: string; +} + +export interface IPresenceInfo { + Presence: PersonaPresence; + Activity: string; } export interface IPersonaComponentState { + PresenceProcessed: boolean; + PresenceInfo: IPresenceInfo; } export class PersonaComponent extends React.Component { @@ -101,6 +121,35 @@ export class PersonaComponent extends React.Component { + + if (this.props.showPresence && this.props.userObjectId && !this.state.PresenceProcessed) { + + // get presence-information via MS Graph asynchronously + this.getUserPresenceInfo(this.props.userObjectId) + .then((presenceInfo) => { + this.setState({ + PresenceProcessed: true, + PresenceInfo: presenceInfo + }); + }) + .catch((error) => { + // in case of an error, simply set state "PresenceProcessed" to "true" and leave "PresenceInfo" = "undefined" + Log.error(LogSource, error, this.props.serviceScope); + this.setState({ PresenceProcessed: true }); + }); + } + else { + // if not showing presence-information, simply set state "PresenceProcessed" to "true" and leave "PresenceInfo" = "undefined" + this.setState({ PresenceProcessed: true }); + } } public render() { @@ -145,6 +194,12 @@ export class PersonaComponent extends React.Component; } + + /** + * Performs a MS Graph-call to retrieve presence-information of an Entra ID-user + * @param entraIdUserObjectId Entra ID ObjectId of the user + * @returns Object of type "IPresenceInfo" containing Presence- and Activity-information + */ + private getUserPresenceInfo(entraIdUserObjectId: string): Promise { + + return new Promise((resolve, reject) => { + + const msGraphClientFactory = this.props.serviceScope.consume(MSGraphClientFactory.serviceKey); + msGraphClientFactory.getClient("3") + .then((client) => { + client.api(`/users/${entraIdUserObjectId}/presence`) + .get((error, response: any, rawResponse?: any) => { + + if (error === null && response) { + resolve({ + Presence: this.getPersonaPresenceFromAvailability(response.availability), + Activity: response.activity + }); + } + else if (error) { reject(error); } + }) + }) + .catch((error) => { reject(error); }) + }); + } + + /** + * Returns the Enum-value corresponding to MS Graph's "availability"-string + * @param availability String-value "availability" from MS Graph + * @returns PersonaPresence Enum-value + */ + private getPersonaPresenceFromAvailability(availability: string): PersonaPresence { + switch (availability) { + case 'Busy': + case 'BusyIdle': + return PersonaPresence.busy; + + case 'Available': + case 'AvailableIdle': + return PersonaPresence.online; + + case 'Away': + case 'BeRightBack': + return PersonaPresence.away; + + case 'Offline': + return PersonaPresence.offline; + + case 'DoNotDisturb': + return PersonaPresence.dnd; + + default: + return PersonaPresence.none; + } + } } export class PersonaWebComponent extends BaseWebComponent { diff --git a/search-parts/src/layouts/results/people/PeopleLayout.ts b/search-parts/src/layouts/results/people/PeopleLayout.ts index dad28340..9dafa425 100644 --- a/search-parts/src/layouts/results/people/PeopleLayout.ts +++ b/search-parts/src/layouts/results/people/PeopleLayout.ts @@ -28,6 +28,11 @@ export interface IPeopleLayoutProperties { * Flag indicating if the persona card should be displayed on hover using native LPC */ showPersonaCardNative: boolean; + + /** + * Flag indicating whether to show presence-information or not + */ + showPersonaPresenceInfo: boolean; } export class PeopleLayout extends BaseLayout { @@ -170,6 +175,15 @@ export class PeopleLayout extends BaseLayout { offText: strings.General.OffTextLabel, checked: this.properties.showPersonaCard, }), + this._propertyFieldToogleWithCallout('layoutProperties.showPersonaPresenceInfo', { + label: strings.Layouts.People.ShowPersonaPresenceInfo, + calloutTrigger: this._propertyFieldCalloutTriggers.Hover, + key: 'layoutProperties.showPersonaPresenceInfo', + calloutContent: React.createElement('p', { style: { maxWidth: 250, wordBreak: 'break-word' } }, strings.Layouts.People.ShowPersonaPresenceInfoCalloutMsg), + onText: strings.General.OnTextLabel, + offText: strings.General.OffTextLabel, + checked: this.properties.showPersonaPresenceInfo + }), PropertyPaneChoiceGroup('layoutProperties.personaSize', { label: strings.Layouts.People.PersonaSizeOptionsLabel, options: [ diff --git a/search-parts/src/layouts/results/people/people.html b/search-parts/src/layouts/results/people/people.html index 44d975e7..941a5bc0 100644 --- a/search-parts/src/layouts/results/people/people.html +++ b/search-parts/src/layouts/results/people/people.html @@ -59,7 +59,9 @@ data-persona-size="{{@root.properties.layoutProperties.personaSize}}" data-theme-variant="{{JSONstringify @root.theme}}" data-instance-id="{{@root.instanceId}}" - data-context="{{JSONstringify (truncateContext @root)}}"> + data-context="{{JSONstringify (truncateContext @root)}}" + data-show-presence={{@root.properties.layoutProperties.showPersonaPresenceInfo}} + data-user-object-id="{{slot item @root.slots.PersonQuery}}">