0

I got a spfx webpart has a ListView of Files i get with a search in Sharepoint. Now i want that when i select a item in this listview it will Do the Preview of the file in a file and media component in a sharepoint page.

How can i make this happen? If possible i want to make my spfx component work as the Connect Source for the File and Media component.

Here is the code for my component

import * as React from 'react';
import styles from './TagQueryGeneratorWebPart.module.scss';
import type { ITagQueryGeneratorWebPartProps } from './ITagQueryGeneratorWebPartProps';
import { escape } from '@microsoft/sp-lodash-subset';

import { SPFI } from "@pnp/sp";

import { getSP } from '../../../pnpjsConfig';
import { ISPDocument } from './interfaces';
import { SearchQueryBuilder } from "@pnp/sp/search";
import { IViewField, ListView, SelectionMode } from '@pnp/spfx-controls-react';
import * as moment from 'moment';

export interface ITagQueryGeneratorWebPartState {
  resultDocs: ISPDocument[];
}

const viewFields: IViewField[] = [
  {
    name: 'Title',
    linkPropertyName: 'Path',
    displayName: 'Title',
    sorting: false,
    minWidth: 100,
    maxWidth: 200,
  },
  {
    name: 'FileExtension',
    displayName: 'Ext',
    sorting: false,
    minWidth: 50,
    maxWidth: 50
  },
  {
    name: "ModifiedBy",
    displayName: "Modify By",
    sorting: false,
    minWidth: 100,
  },
  {
    name: "LastUpdate",
    displayName: "Updated",
    minWidth: 150,
    render: (item: any) => {
      const lastUpdate = item["LastUpdate"];
      if (lastUpdate) {
        const lastUpdateDate = moment(lastUpdate);
        return <span>{lastUpdateDate.format('DD/MM/YYYY HH:mm:ss')}</span>;
      }
    }
  }
];

export default class TagQueryGeneratorWebPart extends React.Component<ITagQueryGeneratorWebPartProps, ITagQueryGeneratorWebPartState> {
  private searchInput: HTMLInputElement | null = null;
  private _sp: SPFI;

  constructor(props: ITagQueryGeneratorWebPartProps) {
    super(props);
    this._sp = getSP();
    this.state = {
      resultDocs: []
    };
  }


  private handleSearch = async () => {
    const searchQuery = "isDocument=True AND " + this.searchInput?.value;

    try {

      const builder = SearchQueryBuilder(searchQuery).rowLimit(10);
      const results3 = await this._sp.search(builder);


      console.log("Result3 " + results3.TotalRows);

      const resultDocs: ISPDocument[] = results3.PrimarySearchResults.map((item) => {

        return {
          Title: item?.Title || "",
          FileExtension: item?.FileExtension || "",
          Path: item?.LinkingUrl || "",
          FileType: item?.FileType || "",
          id: item?.UniqueId || "",
          ModifiedBy: item?.Author || "",
          LastUpdate: item?.LastModifiedTime || null,
        }
      });

      resultDocs.forEach(resultDoc => {
        console.log(resultDoc.id + " " + resultDoc.Title + " " + resultDoc.ModifiedBy + " " + resultDoc.LastUpdate);
      });
      this.setState({ resultDocs });

      console.log('Search results:', searchQuery);

    } catch (error) {
      console.error('Error performing search:', error);
    }
  };

  public render(): React.ReactElement<ITagQueryGeneratorWebPartProps> {
    const {
      description,
      userDisplayName
    } = this.props;

    return (
      <section className={`${styles.tagQueryGeneratorWebPart} `}>
        <div className={styles.welcome} >
          <img alt="" src={require('../assets/welcome-light.png')} className={styles.welcomeImage} />
          <h2>Well done, {escape(userDisplayName)}!</h2>
          <div>Web part property value: <strong>{escape(description)}</strong></div>
        </div>
        <div className={styles.tagQueryGeneratorWebPart} >
          <input type="text" ref={(input) => (this.searchInput = input)} />
          <button onClick={this.handleSearch}>Search</button>
        </div>

        <div className={styles.tagQueryGeneratorWebPart}>
          <ListView items={this.state.resultDocs}
            iconFieldName="Path"
            compact={true}
            viewFields={viewFields}
            selectionMode={SelectionMode.single} />
        </div>
      </section>
    );
  }
}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.