Question

I am working on requirement where i am moving document from Library 1 to Library 2 below goes the code , everything working fine but once i click it take some time to move document , i like to show loader or progress bar unless document get move ? any way to achieve this in spfx extension

if (event.selectedRows.length > 0) {
          // Check the selected rows
          event.selectedRows.forEach((row: RowAccessor, index: number) => {
            const docRelativeUrlDest :string = row.getValueByName('FileLeafRef');
            const destinationUrl = this.context.pageContext.web.serverRelativeUrl+'/Documents/' + `${docRelativeUrlDest}`;
            const docRelativeUrl :string = row.getValueByName('FileRef');
            sp.web.getFileByServerRelativePath(docRelativeUrl).moveTo(destinationUrl);
          

                             
          });
      }
Was it helpful?

Solution

@kumar,

Please take a reference of below code:

  @override
  public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
    switch (event.itemId) {
      case 'COMMAND_1':
        this.dialog = new ProgressDialog();
        this.dialog.initprogress = 0;
        this.dialog.show();

        break;
      case 'COMMAND_2':
        Dialog.alert(`${this.properties.sampleTextTwo}`);
        break;
      default:
        throw new Error('Unknown command');
    }
  }

ProgressDialog.tsx:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { BaseDialog, IDialogConfiguration } from '@microsoft/sp-dialog';
import { ProgressIndicator } from 'office-ui-fabric-react/lib/ProgressIndicator';
import { DialogContent } from 'office-ui-fabric-react';
import { sp } from '@pnp/sp';

interface IProgressDialogContentProps {
  DefaultProgress?: number;
  close: () => void;
}

interface IProgressDialogContentState {
  Progress: number;
}

class ProgressDialogContent extends React.Component<IProgressDialogContentProps, IProgressDialogContentState> {

  constructor(props: IProgressDialogContentProps) {
    super(props);
    // Default progress

    this.state = {
      Progress: this.props.DefaultProgress ? this.props.DefaultProgress : 0
    };
  }

  public componentDidMount() {
    // Sleep in loop
    // sp.web.lists.getByTitle('kkkk').items.getAll().then(res => {
    //   console.log(res[0]['ID']);
    //   this.setState({
    //     Progress: 0.5
    //   });
    //   console.log('hh');
    // });

    for (let i = 2; i < 11; i++) {
      setTimeout(() => {
        this.setState({
          Progress: i / 10
        });

        if (this.state.Progress == 1) {
          this.props.close();
        }

      }, 1000);
    }
  }

  public render(): JSX.Element {
    return <DialogContent
      title='Progress bar content'
      showCloseButton={false}
    >
      <ProgressIndicator label="Example" description="Example description" percentComplete={this.state.Progress}></ProgressIndicator>
    </DialogContent>;
  }

}

export default class ProgressDialogDialog extends BaseDialog {
  public initprogress: number;

  constructor() {
    super({ isBlocking: true });
  }

  public render(): void {
    ReactDOM.render(<ProgressDialogContent
      DefaultProgress={this.initprogress}
      close={this.close}
    />, this.domElement);
  }

  public getConfig(): IDialogConfiguration {
    return {
      isBlocking: true
    };
  } 
}

Test:

enter image description here

Demo:

I get some tips from the official sample:

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top