diff --git a/src/FieldPickerListData.ts b/src/FieldPickerListData.ts index 556f888b6..ce95f0dff 100644 --- a/src/FieldPickerListData.ts +++ b/src/FieldPickerListData.ts @@ -1 +1 @@ -export * from './controls/fields/fieldPickerListData/index'; +export * from './controls/fieldPickerListData/index'; diff --git a/src/controls/fields/fieldPickerListData/FieldPickerListData.tsx b/src/controls/fieldPickerListData/FieldPickerListData.tsx similarity index 76% rename from src/controls/fields/fieldPickerListData/FieldPickerListData.tsx rename to src/controls/fieldPickerListData/FieldPickerListData.tsx index 798f4db70..62fa5be66 100644 --- a/src/controls/fields/fieldPickerListData/FieldPickerListData.tsx +++ b/src/controls/fieldPickerListData/FieldPickerListData.tsx @@ -1,19 +1,23 @@ import * as strings from 'ControlStrings'; import * as React from "react"; -import SPservice from "../../../services/SPService"; +import SPservice from "../../services/SPService"; import { escape } from "@microsoft/sp-lodash-subset"; import { TagPicker } from "office-ui-fabric-react/lib/components/pickers/TagPicker/TagPicker"; import { Label } from "office-ui-fabric-react/lib/Label"; import { IFieldPickerListDataProps, IFieldPickerListDataState } from "."; +import * as telemetry from '../../common/telemetry'; export class FieldPickerListData extends React.Component { - private _value: Array; + private _value: any[]; private _spservice: SPservice; + private selectedItems: any[]; constructor(props: IFieldPickerListDataProps) { super(props); + telemetry.track('FieldPickerListData', {}); + // States this.state = { noresultsFoundText: typeof this.props.noresultsFoundText === undefined ? strings.genericNoResultsFoundText : this.props.noresultsFoundText, @@ -25,8 +29,15 @@ export class FieldPickerListData extends React.Component { - let item: { key: string; name: string } = selectedItems[0]; - console.log(`selected items nr: ${selectedItems.length}`); + this.selectedItems = selectedItems; this.props.onSelectedItem(selectedItems); } @@ -75,7 +85,19 @@ export class FieldPickerListData extends React.Component { - const resolvedSugestions: { key: string; name: string }[] = await this.loadListItems(filterText); + let resolvedSugestions: { key: string; name: string }[] = await this.loadListItems(filterText); + + // Filter out the already retrieved items, so that they cannot be selected again + if (this.selectedItems && this.selectedItems.length > 0) { + let filteredSuggestions = []; + for (const suggestion of resolvedSugestions) { + const exists = this.selectedItems.filter(sItem => sItem.key === suggestion.key); + if (!exists || exists.length === 0) { + filteredSuggestions.push(suggestion); + } + } + resolvedSugestions = filteredSuggestions; + } if (resolvedSugestions) { this.setState({ diff --git a/src/controls/fields/fieldPickerListData/IFieldPickerListDataProps.ts b/src/controls/fieldPickerListData/IFieldPickerListDataProps.ts similarity index 99% rename from src/controls/fields/fieldPickerListData/IFieldPickerListDataProps.ts rename to src/controls/fieldPickerListData/IFieldPickerListDataProps.ts index 6e3a15812..133c15873 100644 --- a/src/controls/fields/fieldPickerListData/IFieldPickerListDataProps.ts +++ b/src/controls/fieldPickerListData/IFieldPickerListDataProps.ts @@ -1,5 +1,6 @@ import { WebPartContext } from "@microsoft/sp-webpart-base"; import { ApplicationCustomizerContext } from "@microsoft/sp-application-base"; + export interface IFieldPickerListDataProps { listId: string; columnInternalName:string; diff --git a/src/controls/fields/fieldPickerListData/IFieldPickerListDataState.ts b/src/controls/fieldPickerListData/IFieldPickerListDataState.ts similarity index 100% rename from src/controls/fields/fieldPickerListData/IFieldPickerListDataState.ts rename to src/controls/fieldPickerListData/IFieldPickerListDataState.ts diff --git a/src/controls/fields/fieldPickerListData/index.ts b/src/controls/fieldPickerListData/index.ts similarity index 82% rename from src/controls/fields/fieldPickerListData/index.ts rename to src/controls/fieldPickerListData/index.ts index 2341a4327..99315e560 100644 --- a/src/controls/fields/fieldPickerListData/index.ts +++ b/src/controls/fieldPickerListData/index.ts @@ -1,5 +1,4 @@ // A file is required to be in the root of the /src directory by the TypeScript compiler export * from './IFieldPickerListDataProps'; export * from './IFieldPickerListDataState'; -export * from '../../../services/SPService'; export * from './FieldPickerListData'; diff --git a/src/services/SPService.ts b/src/services/SPService.ts index bd97eff7a..f17360561 100644 --- a/src/services/SPService.ts +++ b/src/services/SPService.ts @@ -3,15 +3,10 @@ import { ISPLists } from "../common/SPEntities"; import { WebPartContext } from "@microsoft/sp-webpart-base"; import { ApplicationCustomizerContext } from "@microsoft/sp-application-base"; import { SPHttpClient, SPHttpClientResponse } from "@microsoft/sp-http"; -import { sp, Web } from "@pnp/sp"; export default class SPService implements ISPService { - constructor(private _context: WebPartContext | ApplicationCustomizerContext) { - sp.setup({ - spfxContext: this._context - }); - } + constructor(private _context: WebPartContext | ApplicationCustomizerContext) {} /** * Get lists or libraries @@ -47,19 +42,19 @@ export default class SPService implements ISPService { * Get List Items */ public async getListItems(filterText: string, listId: string, internalColumnName: string, webUrl?: string): Promise { - let filter = `startswith(${internalColumnName},'${filterText}')`; - let returnItems: any[]; - let spWeb: Web; - if (typeof webUrl === undefined) { - spWeb = new Web(webUrl); - } else { - spWeb = new Web(this._context.pageContext.web.absoluteUrl); - } try { - returnItems = await spWeb.lists.getById(listId).items.select("Id", internalColumnName).filter(filter).get(); - return Promise.resolve(returnItems); + const apiUrl = `${this._context.pageContext.web.absoluteUrl}/_api/web/lists('${listId}')/items?$select=Id,${internalColumnName}&$filter=startswith(${internalColumnName},'${filterText}')`; + const data = await this._context.spHttpClient.get(apiUrl, SPHttpClient.configurations.v1); + if (data.ok) { + const results = await data.json(); + if (results && results.value && results.value.length > 0) { + return results.value; + } + } + + return []; } catch (error) { return Promise.reject(error); } diff --git a/src/webparts/controlsTest/components/ControlsTest.tsx b/src/webparts/controlsTest/components/ControlsTest.tsx index fa57836d4..a37ed0eb4 100644 --- a/src/webparts/controlsTest/components/ControlsTest.tsx +++ b/src/webparts/controlsTest/components/ControlsTest.tsx @@ -19,6 +19,7 @@ import { SecurityTrimmedControl, PermissionLevel } from '../../../SecurityTrimme import { SPPermission } from '@microsoft/sp-page-context'; import { PeoplePicker, PrincipalType } from '../../../PeoplePicker'; import { getItemClassNames } from 'office-ui-fabric-react/lib/components/ContextualMenu/ContextualMenu.classNames'; +import { FieldPickerListData } from "../../../../lib/FieldPickerListData"; /** * Component that can be used to test out the React controls from this project @@ -32,7 +33,8 @@ export default class ControlsTest extends React.Component { console.log("Lists:", lists); + this.setState({ + selectedList: typeof lists === "string" ? lists : lists.pop() + }); } /** @@ -135,13 +140,22 @@ private onServicePickerChange(terms: IPickerTerms): void { }); } } - /** Method that retrieves the selected items from People Picker + + /** + * Method that retrieves the selected items from People Picker * @param items */ private _getPeoplePickerItems(items: any[]) { console.log('Items:', items); } + /** + * Selected item from the list data picker + */ + private fieldPickerListDataSelected(item: any) { + console.log(item); + } + /** * Renders the component */ @@ -262,6 +276,14 @@ private onServicePickerChange(terms: IPickerTerms): void { onSelectionChanged={this.onListPickerChange} /> +
Field picker list data tester: + +
+
Services tester: