Aktualisiere Version auf 1.2.0, füge Unterstützung für einen konfigurierbaren WebPart-Titel hinzu und verbessere die Darstellung im Accordion-WebPart

This commit is contained in:
Torsten Brendgen
2026-08-27 00:13:33 +02:00
parent b9c0f1de47
commit b6589dd7a5
12 changed files with 28 additions and 11 deletions
+3 -2
View File
@@ -1,6 +1,6 @@
# Accordion # Accordion
Accordion 1.1.2 ist ein listenbasiertes SPFx-WebPart für SharePoint Server Subscription Edition. Es orientiert Accordion 1.2.0 ist ein listenbasiertes SPFx-WebPart für SharePoint Server Subscription Edition. Es orientiert
sich funktional am PnP-Beispiel `react-accordion-dynamic-section`, verwendet aber die mit SharePoint SE sich funktional am PnP-Beispiel `react-accordion-dynamic-section`, verwendet aber die mit SharePoint SE
kompatible SPFx-1.4.1-/React-15-Toolchain. kompatible SPFx-1.4.1-/React-15-Toolchain.
@@ -8,6 +8,7 @@ kompatible SPFx-1.4.1-/React-15-Toolchain.
- Auswahl einer nicht ausgeblendeten Liste aus dem aktuellen Web - Auswahl einer nicht ausgeblendeten Liste aus dem aktuellen Web
- dynamische Auswahl von Überschrift-, Inhalt-, Kategorie- und Sortierspalte - dynamische Auswahl von Überschrift-, Inhalt-, Kategorie- und Sortierspalte
- konfigurierbarer WebPart-Titel
- optionales Gruppieren nach Kategorien - optionales Gruppieren nach Kategorien
- Filter auf eine konkrete, aktuell in der Liste verwendete Kategorie - Filter auf eine konkrete, aktuell in der Liste verwendete Kategorie
- ein- und mehrwertige Managed-Metadata-Spalten als Kategorien - ein- und mehrwertige Managed-Metadata-Spalten als Kategorien
@@ -40,7 +41,7 @@ nächsten Laden beziehungsweise Rendern der Seite automatisch.
| Eigenschaft | Wert | | Eigenschaft | Wert |
|---|---| |---|---|
| Version | 1.1.2 | | Version | 1.2.0 |
| SharePoint Framework | 1.4.1 | | SharePoint Framework | 1.4.1 |
| React | 15.6.2 | | React | 15.6.2 |
| Node.js | 8.17.0 | | Node.js | 8.17.0 |
+1 -1
View File
@@ -4,7 +4,7 @@
"name": "accordion-web-part", "name": "accordion-web-part",
"title": "accordion-web-part", "title": "accordion-web-part",
"id": "27a6fd90-42a1-4e39-8862-08ed0e7803bc", "id": "27a6fd90-42a1-4e39-8862-08ed0e7803bc",
"version": "1.1.2.0", "version": "1.2.0.0",
"includeClientSideAssets": true, "includeClientSideAssets": true,
"skipFeatureDeployment": true "skipFeatureDeployment": true
}, },
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "accordion-web-part", "name": "accordion-web-part",
"version": "1.1.2", "version": "1.2.0",
"private": true, "private": true,
"main": "lib/index.js", "main": "lib/index.js",
"engines": { "engines": {
@@ -16,6 +16,7 @@
}, },
"officeFabricIconFontName": "BulletedList2", "officeFabricIconFontName": "BulletedList2",
"properties": { "properties": {
"title": "Accordion",
"listId": "", "listId": "",
"titleField": "Title", "titleField": "Title",
"contentField": "", "contentField": "",
@@ -6,6 +6,7 @@ import {
IPropertyPaneConfiguration, IPropertyPaneConfiguration,
IPropertyPaneDropdownOption, IPropertyPaneDropdownOption,
PropertyPaneDropdown, PropertyPaneDropdown,
PropertyPaneTextField,
PropertyPaneToggle PropertyPaneToggle
} from '@microsoft/sp-webpart-base'; } from '@microsoft/sp-webpart-base';
import * as strings from 'AccordionWebPartStrings'; import * as strings from 'AccordionWebPartStrings';
@@ -21,6 +22,7 @@ import {
import styles from './components/Accordion.module.scss'; import styles from './components/Accordion.module.scss';
export interface IAccordionWebPartProps { export interface IAccordionWebPartProps {
title: string;
listId: string; listId: string;
titleField: string; titleField: string;
contentField: string; contentField: string;
@@ -73,6 +75,7 @@ export default class AccordionWebPart extends BaseClientSideWebPart<IAccordionWe
if (!items.length) { this.renderStatus(strings.EmptyMessage, false); return; } if (!items.length) { this.renderStatus(strings.EmptyMessage, false); return; }
const element: React.ReactElement<IAccordionProps> = React.createElement(Accordion, { const element: React.ReactElement<IAccordionProps> = React.createElement(Accordion, {
items: items, items: items,
title: this.properties.title || strings.DefaultTitle,
allowMultiple: this.properties.allowMultiple === true, allowMultiple: this.properties.allowMultiple === true,
initialState: this.normalizeInitialState(this.properties.initialState), initialState: this.normalizeInitialState(this.properties.initialState),
showCategories: this.properties.showCategories !== false && !!this.properties.categoryField, showCategories: this.properties.showCategories !== false && !!this.properties.categoryField,
@@ -151,6 +154,7 @@ export default class AccordionWebPart extends BaseClientSideWebPart<IAccordionWe
groups: [{ groups: [{
groupName: strings.DataGroupName, groupName: strings.DataGroupName,
groupFields: [ groupFields: [
PropertyPaneTextField('title', { label: strings.WebPartTitleFieldLabel }),
PropertyPaneDropdown('listId', { PropertyPaneDropdown('listId', {
label: strings.ListFieldLabel, label: strings.ListFieldLabel,
options: listOptions, options: listOptions,
@@ -5,6 +5,7 @@
font-size: 14px; font-size: 14px;
color: "[theme: neutralPrimary, default: #323130]"; color: "[theme: neutralPrimary, default: #323130]";
} }
.webPartHeading { font-size: 24px; font-weight: 300; line-height: 32px; margin: 0 0 14px; }
.category { margin: 0 0 20px; } .category { margin: 0 0 20px; }
.categoryTitle { .categoryTitle {
@@ -22,7 +22,8 @@ export default class Accordion extends React.Component<IAccordionProps, IAccordi
public render(): React.ReactElement<any> { // tslint:disable-line:no-any public render(): React.ReactElement<any> { // tslint:disable-line:no-any
const groups: Array<{ name: string; items: IAccordionItem[] }> = this.groupItems(); const groups: Array<{ name: string; items: IAccordionItem[] }> = this.groupItems();
return <div className={styles.accordion}> return <section className={styles.accordion} aria-label={this.props.title}>
{this.props.title && <h2 className={styles.webPartHeading}>{this.props.title}</h2>}
{groups.map((group, groupIndex) => {groups.map((group, groupIndex) =>
<section className={styles.category} key={'group-' + groupIndex}> <section className={styles.category} key={'group-' + groupIndex}>
{this.props.showCategories && group.name {this.props.showCategories && group.name
@@ -31,7 +32,7 @@ export default class Accordion extends React.Component<IAccordionProps, IAccordi
<div>{group.items.map((item: IAccordionItem) => this.renderItem(item, groupIndex))}</div> <div>{group.items.map((item: IAccordionItem) => this.renderItem(item, groupIndex))}</div>
</section> </section>
)} )}
</div>; </section>;
} }
private renderItem(item: IAccordionItem, groupIndex: number): React.ReactElement<any> { // tslint:disable-line:no-any private renderItem(item: IAccordionItem, groupIndex: number): React.ReactElement<any> { // tslint:disable-line:no-any
@@ -2,6 +2,7 @@ import { IAccordionItem, AccordionInitialState } from '../AccordionTypes';
export interface IAccordionProps { export interface IAccordionProps {
items: IAccordionItem[]; items: IAccordionItem[];
title: string;
allowMultiple: boolean; allowMultiple: boolean;
initialState: AccordionInitialState; initialState: AccordionInitialState;
showCategories: boolean; showCategories: boolean;
@@ -9,4 +10,3 @@ export interface IAccordionProps {
collapseLabel: string; collapseLabel: string;
defaultCategory: string; defaultCategory: string;
} }
+3 -1
View File
@@ -3,6 +3,7 @@ define([], function() {
"PropertyPaneDescription": "Wählen Sie die Liste und Spalten für das Akkordeon aus.", "PropertyPaneDescription": "Wählen Sie die Liste und Spalten für das Akkordeon aus.",
"DataGroupName": "Datenquelle", "DataGroupName": "Datenquelle",
"BehaviorGroupName": "Verhalten", "BehaviorGroupName": "Verhalten",
"WebPartTitleFieldLabel": "WebPart-Titel",
"ListFieldLabel": "Liste", "ListFieldLabel": "Liste",
"TitleFieldLabel": "Spalte für Überschrift", "TitleFieldLabel": "Spalte für Überschrift",
"ContentFieldLabel": "Spalte für Inhalt", "ContentFieldLabel": "Spalte für Inhalt",
@@ -25,6 +26,7 @@ define([], function() {
"LoadErrorMessage": "Die Akkordeon-Einträge konnten nicht geladen werden.", "LoadErrorMessage": "Die Akkordeon-Einträge konnten nicht geladen werden.",
"ExpandLabel": "Aufklappen", "ExpandLabel": "Aufklappen",
"CollapseLabel": "Zuklappen", "CollapseLabel": "Zuklappen",
"DefaultCategory": "Weitere" "DefaultCategory": "Weitere",
"DefaultTitle": "Akkordeon"
}; };
}); });
+3 -1
View File
@@ -3,6 +3,7 @@ define([], function() {
"PropertyPaneDescription": "Select the list and columns used by the accordion.", "PropertyPaneDescription": "Select the list and columns used by the accordion.",
"DataGroupName": "Data source", "DataGroupName": "Data source",
"BehaviorGroupName": "Behavior", "BehaviorGroupName": "Behavior",
"WebPartTitleFieldLabel": "Web part title",
"ListFieldLabel": "List", "ListFieldLabel": "List",
"TitleFieldLabel": "Heading column", "TitleFieldLabel": "Heading column",
"ContentFieldLabel": "Content column", "ContentFieldLabel": "Content column",
@@ -25,6 +26,7 @@ define([], function() {
"LoadErrorMessage": "The accordion entries could not be loaded.", "LoadErrorMessage": "The accordion entries could not be loaded.",
"ExpandLabel": "Expand", "ExpandLabel": "Expand",
"CollapseLabel": "Collapse", "CollapseLabel": "Collapse",
"DefaultCategory": "Other" "DefaultCategory": "Other",
"DefaultTitle": "Accordion"
}; };
}); });
+2
View File
@@ -2,6 +2,7 @@ declare interface IAccordionWebPartStrings {
PropertyPaneDescription: string; PropertyPaneDescription: string;
DataGroupName: string; DataGroupName: string;
BehaviorGroupName: string; BehaviorGroupName: string;
WebPartTitleFieldLabel: string;
ListFieldLabel: string; ListFieldLabel: string;
TitleFieldLabel: string; TitleFieldLabel: string;
ContentFieldLabel: string; ContentFieldLabel: string;
@@ -25,6 +26,7 @@ declare interface IAccordionWebPartStrings {
ExpandLabel: string; ExpandLabel: string;
CollapseLabel: string; CollapseLabel: string;
DefaultCategory: string; DefaultCategory: string;
DefaultTitle: string;
} }
declare module 'AccordionWebPartStrings' { declare module 'AccordionWebPartStrings' {
+5 -2
View File
@@ -18,8 +18,8 @@ var component = read('src/webparts/accordion/components/Accordion.tsx');
var sanitizer = read('src/webparts/accordion/AccordionHtmlSanitizer.ts'); var sanitizer = read('src/webparts/accordion/AccordionHtmlSanitizer.ts');
var styles = read('src/webparts/accordion/components/Accordion.module.scss'); var styles = read('src/webparts/accordion/components/Accordion.module.scss');
assert(packageJson.version === '1.1.2', 'Package version must be 1.1.2.'); assert(packageJson.version === '1.2.0', 'Package version must be 1.2.0.');
assert(solution.version === '1.1.2.0', 'Solution version must be 1.1.2.0.'); assert(solution.version === '1.2.0.0', 'Solution version must be 1.2.0.0.');
assert(solution.includeClientSideAssets === true, 'Client-side assets must be included.'); assert(solution.includeClientSideAssets === true, 'Client-side assets must be included.');
assert(solution.skipFeatureDeployment === true, 'Solution must support central deployment.'); assert(solution.skipFeatureDeployment === true, 'Solution must support central deployment.');
assert(packageJson.name === 'accordion-web-part' && solution.name === 'accordion-web-part' && assert(packageJson.name === 'accordion-web-part' && solution.name === 'accordion-web-part' &&
@@ -29,6 +29,9 @@ assert(json('config/package-solution.json').paths.zippedPackage === 'solution/ac
assert(manifest.componentType === 'WebPart', 'Component must be a web part.'); assert(manifest.componentType === 'WebPart', 'Component must be a web part.');
assert(!!config.bundles['accordion-web-part'], 'Accordion bundle is missing.'); assert(!!config.bundles['accordion-web-part'], 'Accordion bundle is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('listId'") >= 0, 'Dynamic list selection is missing.'); assert(webPart.indexOf("PropertyPaneDropdown('listId'") >= 0, 'Dynamic list selection is missing.');
assert(webPart.indexOf("PropertyPaneTextField('title'") >= 0 &&
component.indexOf('styles.webPartHeading') >= 0,
'Configurable web part title is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('contentField'") >= 0, 'Dynamic content field selection is missing.'); assert(webPart.indexOf("PropertyPaneDropdown('contentField'") >= 0, 'Dynamic content field selection is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('categoryField'") >= 0, 'Category field selection is missing.'); assert(webPart.indexOf("PropertyPaneDropdown('categoryField'") >= 0, 'Category field selection is missing.');
assert(webPart.indexOf("PropertyPaneDropdown('selectedCategory'") >= 0, 'Category value filter is missing.'); assert(webPart.indexOf("PropertyPaneDropdown('selectedCategory'") >= 0, 'Category value filter is missing.');