From 3ee4860e2f117bb0839de82079635d55f6464adf Mon Sep 17 00:00:00 2001 From: MuralidharanGSF4527 Date: Wed, 26 Aug 2026 19:11:23 +0530 Subject: [PATCH] Added the share points pdf viewer sample --- SharePoint/SharePoint/.eslintrc.js | 319 ++++++++++++++++++ SharePoint/SharePoint/.gitignore | 34 ++ SharePoint/SharePoint/.npmignore | 16 + SharePoint/SharePoint/.yo-rc.json | 21 ++ SharePoint/SharePoint/README.md | 98 ++++++ SharePoint/SharePoint/config/config.json | 18 + .../config/deploy-azure-storage.json | 7 + .../SharePoint/config/package-solution.json | 40 +++ SharePoint/SharePoint/config/sass.json | 3 + SharePoint/SharePoint/config/serve.json | 6 + .../SharePoint/config/write-manifests.json | 4 + SharePoint/SharePoint/gulpfile.js | 16 + SharePoint/SharePoint/package.json | 38 +++ SharePoint/SharePoint/src/index.ts | 1 + .../pdfviewer/PdfviewerWebPart.manifest.json | 28 ++ .../pdfviewer/PdfviewerWebPart.module.scss | 76 +++++ .../webparts/pdfviewer/PdfviewerWebPart.ts | 195 +++++++++++ .../pdfviewer/assets/welcome-dark.png | Bin 0 -> 12545 bytes .../pdfviewer/assets/welcome-light.png | Bin 0 -> 12816 bytes .../src/webparts/pdfviewer/loc/en-us.js | 16 + .../src/webparts/pdfviewer/loc/mystrings.d.ts | 19 ++ ...7a8b-fa43-424d-9383-5e5a2a782bfd_color.png | Bin 0 -> 10248 bytes ...8b-fa43-424d-9383-5e5a2a782bfd_outline.png | Bin 0 -> 249 bytes SharePoint/SharePoint/tsconfig.json | 35 ++ 24 files changed, 990 insertions(+) create mode 100644 SharePoint/SharePoint/.eslintrc.js create mode 100644 SharePoint/SharePoint/.gitignore create mode 100644 SharePoint/SharePoint/.npmignore create mode 100644 SharePoint/SharePoint/.yo-rc.json create mode 100644 SharePoint/SharePoint/README.md create mode 100644 SharePoint/SharePoint/config/config.json create mode 100644 SharePoint/SharePoint/config/deploy-azure-storage.json create mode 100644 SharePoint/SharePoint/config/package-solution.json create mode 100644 SharePoint/SharePoint/config/sass.json create mode 100644 SharePoint/SharePoint/config/serve.json create mode 100644 SharePoint/SharePoint/config/write-manifests.json create mode 100644 SharePoint/SharePoint/gulpfile.js create mode 100644 SharePoint/SharePoint/package.json create mode 100644 SharePoint/SharePoint/src/index.ts create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.manifest.json create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.module.scss create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.ts create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-dark.png create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-light.png create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/loc/en-us.js create mode 100644 SharePoint/SharePoint/src/webparts/pdfviewer/loc/mystrings.d.ts create mode 100644 SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_color.png create mode 100644 SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_outline.png create mode 100644 SharePoint/SharePoint/tsconfig.json diff --git a/SharePoint/SharePoint/.eslintrc.js b/SharePoint/SharePoint/.eslintrc.js new file mode 100644 index 0000000..562b8f6 --- /dev/null +++ b/SharePoint/SharePoint/.eslintrc.js @@ -0,0 +1,319 @@ +require('@rushstack/eslint-config/patch/modern-module-resolution'); +module.exports = { + extends: ['@microsoft/eslint-config-spfx/lib/profiles/default'], + parserOptions: { tsconfigRootDir: __dirname }, + overrides: [ + { + files: ['*.ts', '*.tsx'], + parser: '@typescript-eslint/parser', + 'parserOptions': { + 'project': './tsconfig.json', + 'ecmaVersion': 2018, + 'sourceType': 'module' + }, + rules: { + // Prevent usage of the JavaScript null value, while allowing code to access existing APIs that may require null. https://www.npmjs.com/package/@rushstack/eslint-plugin + '@rushstack/no-new-null': 1, + // Require Jest module mocking APIs to be called before any other statements in their code block. https://www.npmjs.com/package/@rushstack/eslint-plugin + '@rushstack/hoist-jest-mock': 1, + // Require regular expressions to be constructed from string constants rather than dynamically building strings at runtime. https://www.npmjs.com/package/@rushstack/eslint-plugin-security + '@rushstack/security/no-unsafe-regexp': 1, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/adjacent-overload-signatures': 1, + // RATIONALE: Code is more readable when the type of every variable is immediately obvious. + // Even if the compiler may be able to infer a type, this inference will be unavailable + // to a person who is reviewing a GitHub diff. This rule makes writing code harder, + // but writing code is a much less important activity than reading it. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/explicit-function-return-type': [ + 1, + { + 'allowExpressions': true, + 'allowTypedFunctionExpressions': true, + 'allowHigherOrderFunctions': false + } + ], + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + // Rationale to disable: although this is a recommended rule, it is up to dev to select coding style. + // Set to 1 (warning) or 2 (error) to enable. + '@typescript-eslint/explicit-member-accessibility': 0, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/no-array-constructor': 1, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + // + // RATIONALE: The "any" keyword disables static type checking, the main benefit of using TypeScript. + // This rule should be suppressed only in very special cases such as JSON.stringify() + // where the type really can be anything. Even if the type is flexible, another type + // may be more appropriate such as "unknown", "{}", or "Record". + '@typescript-eslint/no-explicit-any': 1, + // RATIONALE: The #1 rule of promises is that every promise chain must be terminated by a catch() + // handler. Thus wherever a Promise arises, the code must either append a catch handler, + // or else return the object to a caller (who assumes this responsibility). Unterminated + // promise chains are a serious issue. Besides causing errors to be silently ignored, + // they can also cause a NodeJS process to terminate unexpectedly. + '@typescript-eslint/no-floating-promises': 2, + // RATIONALE: Catches a common coding mistake. + '@typescript-eslint/no-for-in-array': 2, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/no-misused-new': 2, + // RATIONALE: The "namespace" keyword is not recommended for organizing code because JavaScript lacks + // a "using" statement to traverse namespaces. Nested namespaces prevent certain bundler + // optimizations. If you are declaring loose functions/variables, it's better to make them + // static members of a class, since classes support property getters and their private + // members are accessible by unit tests. Also, the exercise of choosing a meaningful + // class name tends to produce more discoverable APIs: for example, search+replacing + // the function "reverse()" is likely to return many false matches, whereas if we always + // write "Text.reverse()" is more unique. For large scale organization, it's recommended + // to decompose your code into separate NPM packages, which ensures that component + // dependencies are tracked more conscientiously. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/no-namespace': [ + 1, + { + 'allowDeclarations': false, + 'allowDefinitionFiles': false + } + ], + // RATIONALE: Parameter properties provide a shorthand such as "constructor(public title: string)" + // that avoids the effort of declaring "title" as a field. This TypeScript feature makes + // code easier to write, but arguably sacrifices readability: In the notes for + // "@typescript-eslint/member-ordering" we pointed out that fields are central to + // a class's design, so we wouldn't want to bury them in a constructor signature + // just to save some typing. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + // Set to 1 (warning) or 2 (error) to enable the rule + '@typescript-eslint/parameter-properties': 0, + // RATIONALE: When left in shipping code, unused variables often indicate a mistake. Dead code + // may impact performance. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/no-unused-vars': [ + 1, + { + 'vars': 'all', + // Unused function arguments often indicate a mistake in JavaScript code. However in TypeScript code, + // the compiler catches most of those mistakes, and unused arguments are fairly common for type signatures + // that are overriding a base class method or implementing an interface. + 'args': 'none' + } + ], + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/no-use-before-define': [ + 2, + { + 'functions': false, + 'classes': true, + 'variables': true, + 'enums': true, + 'typedefs': true + } + ], + // Disallows require statements except in import statements. + // In other words, the use of forms such as var foo = require("foo") are banned. Instead use ES6 style imports or import foo = require("foo") imports. + '@typescript-eslint/no-var-requires': 'error', + // RATIONALE: The "module" keyword is deprecated except when describing legacy libraries. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + '@typescript-eslint/prefer-namespace-keyword': 1, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + // Rationale to disable: it's up to developer to decide if he wants to add type annotations + // Set to 1 (warning) or 2 (error) to enable the rule + '@typescript-eslint/no-inferrable-types': 0, + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + // Rationale to disable: declaration of empty interfaces may be helpful for generic types scenarios + '@typescript-eslint/no-empty-interface': 0, + // RATIONALE: This rule warns if setters are defined without getters, which is probably a mistake. + 'accessor-pairs': 1, + // RATIONALE: In TypeScript, if you write x["y"] instead of x.y, it disables type checking. + 'dot-notation': [ + 1, + { + 'allowPattern': '^_' + } + ], + // RATIONALE: Catches code that is likely to be incorrect + 'eqeqeq': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'for-direction': 1, + // RATIONALE: Catches a common coding mistake. + 'guard-for-in': 2, + // RATIONALE: If you have more than 2,000 lines in a single source file, it's probably time + // to split up your code. + 'max-lines': ['warn', { max: 2000 }], + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-async-promise-executor': 2, + // RATIONALE: Deprecated language feature. + 'no-caller': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-compare-neg-zero': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-cond-assign': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-constant-condition': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-control-regex': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-debugger': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-delete-var': 2, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-duplicate-case': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-empty': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-empty-character-class': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-empty-pattern': 1, + // RATIONALE: Eval is a security concern and a performance concern. + 'no-eval': 1, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-ex-assign': 2, + // RATIONALE: System types are global and should not be tampered with in a scalable code base. + // If two different libraries (or two versions of the same library) both try to modify + // a type, only one of them can win. Polyfills are acceptable because they implement + // a standardized interoperable contract, but polyfills are generally coded in plain + // JavaScript. + 'no-extend-native': 1, + // Disallow unnecessary labels + 'no-extra-label': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-fallthrough': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-func-assign': 1, + // RATIONALE: Catches a common coding mistake. + 'no-implied-eval': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-invalid-regexp': 2, + // RATIONALE: Catches a common coding mistake. + 'no-label-var': 2, + // RATIONALE: Eliminates redundant code. + 'no-lone-blocks': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-misleading-character-class': 2, + // RATIONALE: Catches a common coding mistake. + 'no-multi-str': 2, + // RATIONALE: It's generally a bad practice to call "new Thing()" without assigning the result to + // a variable. Either it's part of an awkward expression like "(new Thing()).doSomething()", + // or else implies that the constructor is doing nontrivial computations, which is often + // a poor class design. + 'no-new': 1, + // RATIONALE: Obsolete language feature that is deprecated. + 'no-new-func': 2, + // RATIONALE: Obsolete language feature that is deprecated. + 'no-new-object': 2, + // RATIONALE: Obsolete notation. + 'no-new-wrappers': 1, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-octal': 2, + // RATIONALE: Catches code that is likely to be incorrect + 'no-octal-escape': 2, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-regex-spaces': 2, + // RATIONALE: Catches a common coding mistake. + 'no-return-assign': 2, + // RATIONALE: Security risk. + 'no-script-url': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-self-assign': 2, + // RATIONALE: Catches a common coding mistake. + 'no-self-compare': 2, + // RATIONALE: This avoids statements such as "while (a = next(), a && a.length);" that use + // commas to create compound expressions. In general code is more readable if each + // step is split onto a separate line. This also makes it easier to set breakpoints + // in the debugger. + 'no-sequences': 1, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-shadow-restricted-names': 2, + // RATIONALE: Obsolete language feature that is deprecated. + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-sparse-arrays': 2, + // RATIONALE: Although in theory JavaScript allows any possible data type to be thrown as an exception, + // such flexibility adds pointless complexity, by requiring every catch block to test + // the type of the object that it receives. Whereas if catch blocks can always assume + // that their object implements the "Error" contract, then the code is simpler, and + // we generally get useful additional information like a call stack. + 'no-throw-literal': 2, + // RATIONALE: Catches a common coding mistake. + 'no-unmodified-loop-condition': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-unsafe-finally': 2, + // RATIONALE: Catches a common coding mistake. + 'no-unused-expressions': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-unused-labels': 1, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-useless-catch': 1, + // RATIONALE: Avoids a potential performance problem. + 'no-useless-concat': 1, + // RATIONALE: The "var" keyword is deprecated because of its confusing "hoisting" behavior. + // Always use "let" or "const" instead. + // + // STANDARDIZED BY: @typescript-eslint\eslint-plugin\dist\configs\recommended.json + 'no-var': 2, + // RATIONALE: Generally not needed in modern code. + 'no-void': 1, + // RATIONALE: Obsolete language feature that is deprecated. + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'no-with': 2, + // RATIONALE: Makes logic easier to understand, since constants always have a known value + // @typescript-eslint\eslint-plugin\dist\configs\eslint-recommended.js + 'prefer-const': 1, + // RATIONALE: Catches a common coding mistake where "resolve" and "reject" are confused. + 'promise/param-names': 2, + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'require-atomic-updates': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'require-yield': 1, + // "Use strict" is redundant when using the TypeScript compiler. + 'strict': [ + 2, + 'never' + ], + // RATIONALE: Catches code that is likely to be incorrect + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + 'use-isnan': 2, + // STANDARDIZED BY: eslint\conf\eslint-recommended.js + // Set to 1 (warning) or 2 (error) to enable. + // Rationale to disable: !!{} + 'no-extra-boolean-cast': 0, + // ==================================================================== + // @microsoft/eslint-plugin-spfx + // ==================================================================== + '@microsoft/spfx/import-requires-chunk-name': 1, + '@microsoft/spfx/no-require-ensure': 2, + '@microsoft/spfx/pair-react-dom-render-unmount': 1 + } + }, + { + // For unit tests, we can be a little bit less strict. The settings below revise the + // defaults specified in the extended configurations, as well as above. + files: [ + // Test files + '*.test.ts', + '*.test.tsx', + '*.spec.ts', + '*.spec.tsx', + + // Facebook convention + '**/__mocks__/*.ts', + '**/__mocks__/*.tsx', + '**/__tests__/*.ts', + '**/__tests__/*.tsx', + + // Microsoft convention + '**/test/*.ts', + '**/test/*.tsx' + ], + rules: {} + } + ] +}; \ No newline at end of file diff --git a/SharePoint/SharePoint/.gitignore b/SharePoint/SharePoint/.gitignore new file mode 100644 index 0000000..51ca7b9 --- /dev/null +++ b/SharePoint/SharePoint/.gitignore @@ -0,0 +1,34 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependency directories +node_modules + +# Build generated files +dist +lib +release +solution +temp +*.sppkg +.heft + +# Coverage directory used by tools like istanbul +coverage + +# OSX +.DS_Store + +# Visual Studio files +.ntvs_analysis.dat +.vs +bin +obj + +# Resx Generated Code +*.resx.ts + +# Styles Generated Code +*.scss.ts diff --git a/SharePoint/SharePoint/.npmignore b/SharePoint/SharePoint/.npmignore new file mode 100644 index 0000000..ae0b487 --- /dev/null +++ b/SharePoint/SharePoint/.npmignore @@ -0,0 +1,16 @@ +!dist +config + +gulpfile.js + +release +src +temp + +tsconfig.json +tslint.json + +*.log + +.yo-rc.json +.vscode diff --git a/SharePoint/SharePoint/.yo-rc.json b/SharePoint/SharePoint/.yo-rc.json new file mode 100644 index 0000000..5888527 --- /dev/null +++ b/SharePoint/SharePoint/.yo-rc.json @@ -0,0 +1,21 @@ +{ + "@microsoft/generator-sharepoint": { + "plusBeta": false, + "isCreatingSolution": true, + "nodeVersion": "20.18.2", + "sdksVersions": { + "@microsoft/microsoft-graph-client": "3.0.2", + "@microsoft/teams-js": "2.24.0" + }, + "version": "1.20.0", + "libraryName": "pdfviewer-spfx", + "libraryId": "756ebdc3-ddeb-495b-b837-e56bc0ee5c70", + "environment": "spo", + "packageManager": "npm", + "solutionName": "pdfviewer-spfx", + "solutionShortDescription": "pdfviewer-spfx description", + "skipFeatureDeployment": true, + "isDomainIsolated": false, + "componentType": "webpart" + } +} diff --git a/SharePoint/SharePoint/README.md b/SharePoint/SharePoint/README.md new file mode 100644 index 0000000..424b359 --- /dev/null +++ b/SharePoint/SharePoint/README.md @@ -0,0 +1,98 @@ +# SharePoint PDF Viewer Web Part + +A SharePoint Framework (SPFx) web part that integrates **Syncfusion EJ2 PDF Viewer** for viewing PDF documents stored in SharePoint. This application provides a view-only mode with a user-friendly interface for document selection and navigation. + +## 📦 Installation + +### Prerequisites +- A SharePoint development environment and a Microsoft 365 tenant (for testing/deployment). +- Node.js compatible with your SPFx version (check SPFx docs). This application requires 20.18.2 +- Gulp: `npm install -g gulp-cli`. + +### Setup Steps + +1. **Clone/Extract the project** + ```bash + cd typescript-pdf-viewer-examples/SharePoint + ``` + +2. **Install dependencies** + ```bash + npm install + ``` + +3. **Configure PDF Source Location** + Edit `src/webparts/pdfviewer/PdfviewerWebPart.ts`: + - Replace `YOUR-SHAREPOINT-SITE` with your SharePoint site URL + - Replace `{your-site-name}` with your site name + - Replace `{documents-containing-path}` with the path to your PDF documents folder + + ```typescript + const url = `${targetSite}/_api/web/GetFolderByServerRelativeUrl('/sites/{your-site-name}/{documents-containing-path}')/Files`; + ``` + +4. **Configure Resource URL** (Optional) + Update the `resourceUrl` in the PDF Viewer initialization: + ```typescript + resourceUrl: '${YOUR-LOCATION-FOR-RESOURCE}/ej2-pdfviewer-lib' + ``` + +## Run the application + +### Development Build + +```bash +gulp serve +``` + +The sample will be hosted in `https://{tenantDomain}/_layouts/workbench.aspx`. + +## 📖 Usage + +### Adding the Web Part to a Page + +1. Navigate to a SharePoint page (modern or full page) +2. Click **Edit** to enter edit mode +3. Click **+ Add a new web part** +4. Search for **"pdfviewer"** (labeled as "Advanced" category) +5. Click to add the web part +6. The web part will load available PDF documents from the configured location +7. Use the dropdown menu to select a PDF document +8. The selected document will load in the viewer + +### Web Part Configuration + +**Property Pane Settings** +- Navigate to the web part menu → **Edit web part** +- **Basic Settings**: + - **Description**: Add a description for the web part (for reference) + +### Toolbar Options (View-Only Mode) + +The toolbar displays the following tools: +- **Open Option**: Load a different document +- **Page Navigation Tool**: Jump to specific pages +- **Magnification Tool**: Zoom controls +- **Pan Tool**: Navigate large pages +- **Print Option**: Print the document + +## View-Only Mode + +### Form Fields +All form fields are automatically set to **read-only** when the document loads: +```typescript +viewer.formDesignerModule.updateFormField(viewer.formFieldCollections[x], { + isReadOnly: true, +}); +``` + +### Disabled Features +- Annotations and sticky notes +- Page organizer +- Context menu interactions +- Direct form field editing + +## 🔗 Resources + +- [Syncfusion Javascript PDF Viewer](https://www.syncfusion.com/pdf-viewer-sdk/javascript-pdf-viewer) +- [Documentation](https://help.syncfusion.com/document-processing/pdf/pdf-viewer/react/depoyment-integration/share-point) \ No newline at end of file diff --git a/SharePoint/SharePoint/config/config.json b/SharePoint/SharePoint/config/config.json new file mode 100644 index 0000000..3d7c825 --- /dev/null +++ b/SharePoint/SharePoint/config/config.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json", + "version": "2.0", + "bundles": { + "pdfviewer-web-part": { + "components": [ + { + "entrypoint": "./lib/webparts/pdfviewer/PdfviewerWebPart.js", + "manifest": "./src/webparts/pdfviewer/PdfviewerWebPart.manifest.json" + } + ] + } + }, + "externals": {}, + "localizedResources": { + "PdfviewerWebPartStrings": "lib/webparts/pdfviewer/loc/{locale}.js" + } +} diff --git a/SharePoint/SharePoint/config/deploy-azure-storage.json b/SharePoint/SharePoint/config/deploy-azure-storage.json new file mode 100644 index 0000000..d745a6c --- /dev/null +++ b/SharePoint/SharePoint/config/deploy-azure-storage.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json", + "workingDir": "./release/assets/", + "account": "", + "container": "pdfviewer-spfx", + "accessKey": "" +} \ No newline at end of file diff --git a/SharePoint/SharePoint/config/package-solution.json b/SharePoint/SharePoint/config/package-solution.json new file mode 100644 index 0000000..2b69200 --- /dev/null +++ b/SharePoint/SharePoint/config/package-solution.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json", + "solution": { + "name": "pdfviewer-spfx-client-side-solution", + "id": "756ebdc3-ddeb-495b-b837-e56bc0ee5c70", + "version": "1.0.0.0", + "includeClientSideAssets": true, + "skipFeatureDeployment": true, + "isDomainIsolated": false, + "developer": { + "name": "", + "websiteUrl": "", + "privacyUrl": "", + "termsOfUseUrl": "", + "mpnId": "Undefined-1.20.0" + }, + "metadata": { + "shortDescription": { + "default": "pdfviewer-spfx description" + }, + "longDescription": { + "default": "pdfviewer-spfx description" + }, + "screenshotPaths": [], + "videoUrl": "", + "categories": [] + }, + "features": [ + { + "title": "pdfviewer-spfx Feature", + "description": "The feature that activates elements of the pdfviewer-spfx solution.", + "id": "c3b9ea15-4bf5-4e7d-abe4-2b039c7de9d0", + "version": "1.0.0.0" + } + ] + }, + "paths": { + "zippedPackage": "solution/pdfviewer-spfx.sppkg" + } +} diff --git a/SharePoint/SharePoint/config/sass.json b/SharePoint/SharePoint/config/sass.json new file mode 100644 index 0000000..5e78c98 --- /dev/null +++ b/SharePoint/SharePoint/config/sass.json @@ -0,0 +1,3 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/core-build/sass.schema.json" +} \ No newline at end of file diff --git a/SharePoint/SharePoint/config/serve.json b/SharePoint/SharePoint/config/serve.json new file mode 100644 index 0000000..a4c03e2 --- /dev/null +++ b/SharePoint/SharePoint/config/serve.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/spfx-serve.schema.json", + "port": 4321, + "https": true, + "initialPage": "https://{tenantDomain}/_layouts/workbench.aspx" +} diff --git a/SharePoint/SharePoint/config/write-manifests.json b/SharePoint/SharePoint/config/write-manifests.json new file mode 100644 index 0000000..bad3526 --- /dev/null +++ b/SharePoint/SharePoint/config/write-manifests.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json", + "cdnBasePath": "" +} \ No newline at end of file diff --git a/SharePoint/SharePoint/gulpfile.js b/SharePoint/SharePoint/gulpfile.js new file mode 100644 index 0000000..be29187 --- /dev/null +++ b/SharePoint/SharePoint/gulpfile.js @@ -0,0 +1,16 @@ +'use strict'; + +const build = require('@microsoft/sp-build-web'); + +build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`); + +var getTasks = build.rig.getTasks; +build.rig.getTasks = function () { + var result = getTasks.call(build.rig); + + result.set('serve', result.get('serve-deprecated')); + + return result; +}; + +build.initialize(require('gulp')); diff --git a/SharePoint/SharePoint/package.json b/SharePoint/SharePoint/package.json new file mode 100644 index 0000000..a237da0 --- /dev/null +++ b/SharePoint/SharePoint/package.json @@ -0,0 +1,38 @@ +{ + "name": "pdfviewer-spfx", + "version": "0.0.1", + "private": true, + "engines": { + "node": ">=18.17.1 <19.0.0" + }, + "main": "lib/index.js", + "scripts": { + "build": "gulp bundle", + "clean": "gulp clean", + "test": "gulp test" + }, + "dependencies": { + "@microsoft/sp-component-base": "1.20.0", + "@microsoft/sp-core-library": "1.20.0", + "@microsoft/sp-lodash-subset": "1.20.0", + "@microsoft/sp-office-ui-fabric-core": "1.20.0", + "@microsoft/sp-property-pane": "1.20.0", + "@microsoft/sp-webpart-base": "1.20.0", + "@syncfusion/ej2-pdfviewer": "^34.2.5", + "tslib": "2.3.1" + }, + "devDependencies": { + "@fluentui/react": "^8.106.4", + "@microsoft/eslint-config-spfx": "1.20.2", + "@microsoft/eslint-plugin-spfx": "1.20.2", + "@microsoft/rush-stack-compiler-4.7": "0.1.0", + "@microsoft/sp-build-web": "1.20.2", + "@microsoft/sp-module-interfaces": "1.20.2", + "@rushstack/eslint-config": "4.0.1", + "@types/webpack-env": "~1.15.2", + "ajv": "^6.12.5", + "eslint": "8.57.0", + "gulp": "4.0.2", + "typescript": "4.7.4" + } +} diff --git a/SharePoint/SharePoint/src/index.ts b/SharePoint/SharePoint/src/index.ts new file mode 100644 index 0000000..fb81db1 --- /dev/null +++ b/SharePoint/SharePoint/src/index.ts @@ -0,0 +1 @@ +// A file is required to be in the root of the /src directory by the TypeScript compiler diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.manifest.json b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.manifest.json new file mode 100644 index 0000000..3924f84 --- /dev/null +++ b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.manifest.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json", + "id": "87887a8b-fa43-424d-9383-5e5a2a782bfd", + "alias": "PdfviewerWebPart", + "componentType": "WebPart", + + // The "*" signifies that the version should be taken from the package.json + "version": "*", + "manifestVersion": 2, + + // If true, the component can only be installed on sites where Custom Script is allowed. + // Components that allow authors to embed arbitrary script code should set this to true. + // https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f + "requiresCustomScript": false, + "supportedHosts": ["SharePointWebPart", "TeamsPersonalApp", "TeamsTab", "SharePointFullPage"], + "supportsThemeVariants": true, + + "preconfiguredEntries": [{ + "groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Advanced + "group": { "default": "Advanced" }, + "title": { "default": "pdfviewer" }, + "description": { "default": "pdfviewer description" }, + "officeFabricIconFontName": "Page", + "properties": { + "description": "pdfviewer" + } + }] +} diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.module.scss b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.module.scss new file mode 100644 index 0000000..3800d1a --- /dev/null +++ b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.module.scss @@ -0,0 +1,76 @@ + +.pdfViewerContainer { + display: flex; + flex-direction: column; + height: 100%; + + .documentSelector { + padding: 15px; + background: #f5f5f5; + border-bottom: 1px solid #ddd; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + + label { + display: block; + margin-bottom: 8px; + font-weight: 600; + color: #333; + font-size: 14px; + } + + select { + width: 100%; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + font-size: 14px; + background-color: white; + cursor: pointer; + transition: border-color 0.3s; + + &:hover { + border-color: #999; + } + + &:focus { + outline: none; + border-color: #0078d4; + box-shadow: 0 0 0 1px #0078d4; + } + } + } + + .statusMessage { + font-size: 12px; + padding: 0 15px; + margin-top: 5px; + + &.loading { + color: #0078d4; + } + + &.error { + color: #d13438; + } + } + + .pdfViewerWrapper { + flex: 1; + overflow: hidden; + } +} + +.emptyState { + display: flex; + align-items: center; + justify-content: center; + height: 100%; + color: #666; + font-size: 14px; + text-align: center; + padding: 20px; + + p { + margin: 0; + } +} diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.ts b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.ts new file mode 100644 index 0000000..af75ea9 --- /dev/null +++ b/SharePoint/SharePoint/src/webparts/pdfviewer/PdfviewerWebPart.ts @@ -0,0 +1,195 @@ + +import { Version } from '@microsoft/sp-core-library'; +import { + IPropertyPaneConfiguration, + PropertyPaneTextField +} from '@microsoft/sp-property-pane'; +import { SPHttpClient } from '@microsoft/sp-http'; +import { + BaseClientSideWebPart +} from '@microsoft/sp-webpart-base'; + +import { PdfViewer, Toolbar, Magnification, Navigation, + Annotation, LinkAnnotation, ThumbnailView, + BookmarkView, TextSelection, TextSearch, + FormFields, FormDesigner } from '@syncfusion/ej2-pdfviewer'; + +PdfViewer.Inject(Toolbar, Magnification, Navigation, + Annotation, LinkAnnotation, ThumbnailView, + BookmarkView, TextSelection, TextSearch, + FormFields, FormDesigner); + +export interface IPdfViewerWebPartProps { + description: string; +} + +interface IPdfFile { + name: string; + url: string; +} + +export default class PdfViewerWebPart extends BaseClientSideWebPart { + + private pdfViewer: PdfViewer | undefined; + private pdfFiles: IPdfFile[] = []; + + public render(): void { + + this.domElement.innerHTML = ` + +
+
+ + +
+
Loading PDF documents from SiteAssets/pdfs...
+ +
+
+ `; + + const siteUrl = this.context.pageContext.web.absoluteUrl; + console.log("Site URL: ", siteUrl); + + // Fetch PDF documents + this.fetchPdfDocuments(siteUrl); + + // Initialize PDF Viewer + this.initializePdfViewer(); + } + + private async fetchPdfDocuments(siteUrl: string): Promise { + try { + const targetSite = "YOUR-SHAREPOINT-SITE"; + + const url = `${targetSite}/_api/web/GetFolderByServerRelativeUrl('/sites/{your-site-name}/{documents-containing-path}')/Files`; + + const response = await this.context.spHttpClient.get( + url, + SPHttpClient.configurations.v1 + ); + + if (!response.ok) { + throw new Error(`Failed to fetch PDFs: ${response.statusText}`); + } + + const data = await response.json(); + + console.log(data); + + this.pdfFiles = data.value + .filter((item: any) => + item.Name.toLowerCase().endsWith('.pdf')) + .map((item: any) => ({ + name: item.Name, + url: `${siteUrl}${item.ServerRelativeUrl}` + })); + + console.log('PDF Files found:', this.pdfFiles); + this.populateDropdown(); + + } catch (error) { + console.error('Error fetching PDF documents:', error); + const errorDiv = document.getElementById('errorMessage'); + if (errorDiv) { + errorDiv.style.display = 'block'; + errorDiv.textContent = `Error loading documents: ${error instanceof Error ? error.message : 'Unknown error'}`; + } + } + } + + private populateDropdown(): void { + const dropdown = document.getElementById('pdfDropdown') as HTMLSelectElement; + const loadingMessage = document.getElementById('loadingMessage'); + + if (!dropdown) return; + + dropdown.innerHTML = ''; + + this.pdfFiles.forEach((file) => { + const option = document.createElement('option'); + option.value = file.url; + option.textContent = file.name; + dropdown.appendChild(option); + }); + + if (loadingMessage) { + loadingMessage.style.display = 'none'; + } + + // Add change event listener + dropdown.addEventListener('change', (e: Event) => { + const selectedUrl = (e.target as HTMLSelectElement).value; + if (selectedUrl) { + this.loadPdfDocument(selectedUrl); + } + }); + } + + private initializePdfViewer(): void { + this.pdfViewer = new PdfViewer({ + documentPath: 'https://cdn.syncfusion.com/content/pdf/gis-succinctly.pdf', // Will be set when user selects a document + resourceUrl: '${YOUR-LOCATION-FOR-RESOURCE}/ej2-pdfviewer-lib', + toolbarSettings: { + showTooltip: true, + toolbarItems: ['OpenOption', 'PageNavigationTool', 'MagnificationTool', 'PanTool', 'PrintOption',] + }, + enableAnnotationToolbar: false, + enableDownload: true, + enableStickyNotesAnnotation: false, + enablePageOrganizer: false, + annotationSettings: { + isLock: true, + }, + contextMenuOption: 'None', + documentLoad: () => { + const viewer = (document.getElementById('PdfViewer') as any).ej2_instances[0]; + const formField = viewer.retrieveFormFields(); + for (let x = 0; x < formField.length; x++) { + viewer.formDesignerModule.updateFormField(viewer.formFieldCollections[x], { + isReadOnly: true, + }); + } + } + }); + + this.pdfViewer.appendTo('#PdfViewer'); + } + + private loadPdfDocument(url: string): void { + if (this.pdfViewer) { + this.pdfViewer.load(url, "null"); + console.log('Loading PDF:', url); + } + } + + protected get dataVersion(): Version { + return Version.parse('1.0'); + } + + protected getPropertyPaneConfiguration(): + IPropertyPaneConfiguration { + + return { + pages: [ + { + header: { + description: 'PDF Viewer Settings' + }, + groups: [ + { + groupName: 'Basic Settings', + groupFields: [ + PropertyPaneTextField('description', { + label: 'Description' + }) + ] + } + ] + } + ] + }; + } +} diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-dark.png b/SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..42f0b8d24a9aa964a2be4885fe5700c1c54191a9 GIT binary patch literal 12545 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�Gp~kbx)oU28ew4C2+WtKA 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 G`2PSf1J4)$ literal 0 HcmV?d00001 diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-light.png b/SharePoint/SharePoint/src/webparts/pdfviewer/assets/welcome-light.png new file mode 100644 index 0000000000000000000000000000000000000000..69eb3b48cd83031f106df4b4df127c749657e319 GIT binary patch literal 12816 zcmaKTWmsF!(>7Av-Jwt@?(Pl&in|1Ncb6i;i%W|Z_uy{DDef)>iUlq1y!rjF>-qYA z$Vtv-&(6-wJ+rejXJgb<J4-29?4Y^8uyxXi5w@!^8PoT|u2h@%3S) zq5DXkThXAAqF}2vX~~!2*=0;MhHy@ux;CjXc(f)VMF3#d_kO8H724(sZ9_t9gtnos zJ`A78oBUL^>?3AofKr#RU3)d<{5!>2*8M{|roO*F)Y7e{MxIp7*J+C+Ribm}2VT zpgqhEio2hF$*x5#b6lq3KS2UoHkgla)69#~%-KaF!>GMI!r?6*rxC67_b{VIa(Yyw z(xx{XZ?_oJ2bO9K*B1zYSq6!ecKA}K(mk35qV}y9>aBO-oEfccQVn%Kt&49Bd(p?r zE>=67mdvUr4O@8?8PP0~D@GsxoyFI)>`63mN&6=;QD^bFtS@~(oo7s2h{ODRZG_^d zr)W{zSYDhG`F^yBHOEU?UJUs5~Er(ZA)u_2c?&FNvNU9Qd&Bp z;IaSfw7Bw*Z1~JVerse9zQ!g{*Kna#nD#X^BWr(rzIJ6bY!C`Csj;5#CN`;K05&H4*SzyubP#y<5^ww4P_6ujx4)IG@sSiII(5nz_)?p> z6aiWYbJa}A#=L>v60hKf5k)f|keY{f$6LfeY4iN_W<_u?2Om5pE!sTqKpZ|w*`9u} zeJMN)9VB%#V+5TqRFyuE<2OVZqG3{YKe4!W5}82-E?(ZC_SGEW?yDV#_lnswv<)1pTH9z}Uw^bGIAMsTNS`+fGK z<$C1Or-N0M`K$^JrPwqK25cY&1%{TknwO+@WC?SD7II^I;jG!bDpXfu<9&nXC3D&n z2a+eVpNx4OTTmHsHF&nVy-woK)<%p&&h&X@G8R-;8@s6xveO!HxUUu8AMPgCTLb9D zCCq4ZydibhAK_KreXYdU6L`t+9cf&c3(^#3NZU$>7Mnr!AcApZq?Dm52y~>GE<)=~ z(Gc)nMY7CJGdS|J-g8KFVVgQ1GXgFqJC$|p5&#(E6^dGH6Gc2)90+D2Kuyi%4=tu{ zAN9#8%<^W}azJJKd93%&@|5k~XICoO*5Ya$1MWYPY)R2bRXudK`UgYPkhXkZZG|sP zlez*)T8b*m3!5IklJae$@P$^DAjD;pUVSCq^`~U96U)9;O)4n`U8U^ek;|bV`}R}# zA+;Twne9l7!Gr661+S&yvoK2Gsp>s`Sk21=2W2TcVEW|LA0wZ-9T{*(&Gq*|iB0U# z!=6hi>M+$n1ZAW>MK^PiOo_jl{#GwguDJl}*0M}kCn7{1CS8q^)ztD{i@E$pQ>^El z0}5An59->c&taQOJ&5FPeF+5OWY8Chpfqo~4wjR~Y#(M^@tfc4lVlRrqTxNI0iV ztP7K^5*$QaZR(l{%v)W8xU9J*$!GoTPd_y^Obl?{B|i4~isY_Gy}?e#`m00OMG z8s`OjEWc3UkTmi-1IB}pN@iNBuq3u7&G>fIvc_c_52!s+mPmf5x|pk!?+8PN4gZh| zrlG=5QxhbqAyMA_>+#`Eom=VjI|))AZ8#Q!ghiP|{(~reS9;pKmww)tuS>F%I<2U# z+%cKBBGv^USY9vHDBnA-b{Htu>q=1~Dgh7=t;s$U$g$JfUu4**nu8JSSm)P0v_ShP z(qpf=xtYE@Zj^fxOcMBCvRfS;lBDHS$qs(wY-dS(mxm$V7zzB`E0I?b}tl@!{JghGw<(t&75QPVN(qAOk zR}|0xS{}VVD}~U2f8~U{o;R7zACN42pq8ubkbmwr5P;cN`%cjyDL{dZi4@;gP?6Y9 z)OY8Xr-+lp8dsV5ckzcFOGGQCfdrrP20&W_O;2Z)muKpxO{X0>5;e|KcsKUELmFY` zCyCtD)B4ZMOtYghR^kBu9-6}YvZ+o`kFSmt&;LA>A^JWQChaiSOwieyN`cw^muVEr zV8%0!2KFlHS<&p$jf=KEZn~uCf`cm0tw~r<{6Jm#kpf6Z2Vq@Tp9dh`N&;C#c-nd?5ZkE%k)wk_E?U+XL97P{B&JV#E@qsBEC34(gz zGoG7M7e-_VdJlgHEFT4B$2h%+<%k|>N=*XIpmM9c%X-E#wPEbyi^k(#SMSjmPcj#& z9Cm>uVx{oUH=BUe(#V5`-#S19K2b==-lv&scqCj4#zHT7xCU4j7u$}WL^AT~MEIC` z{K=McTP|vh6*zc6dKzv8E*G*{e7N!sW_){_VuJuw%o?;2-XRUsi&_F{=(*t*)d9nY zLGOY5l+VYE*Gc)NrsQw4W)G2jJ{Av8NV?L~KVndO=lUA!zFn)Rr`l!Reb7}{8isO< z3SCu6HSDZiAB41rxcE-46FhHrk(knikdQbxwxdGxDC5zGb+v1aQAFuUz_XZ*2Ig-6 zH-nGprwaRzS;=c1A3HR@|6YJsK&6l_ z6N~LkgrjY#al<`ManSAM%&i=P}Qh#Q1I^=qOaygAiZ+b5Wsplrtiq8akXNjV1f;Hz%1;N>JS?1GHV+cF?Xc^?^ zEscbjv>D66*99h(Q53z{QeUdm_l04Mn`mdCQhj5rLn&{Z41TaF=q_gqtO@qvu0S9nO7&q_`i zV=YKH3GL}M|IcF)et9qUZC7iqm+Qy+E?%}<>reP{$R@N1c$;!^RWy)LNqg3#YN}GvUTK72LXDC@!2eYr4heT$32R%o*KmKjQVsh@Iu0=I z(u+0+yCN%Xv@TaLqb!&g?714KpsipX1teT)6-8bK`k1oKz^(6&1jDm7ZLXw&Mj7EM5<@=P_Ob-zkzHT^uV{7 zKT2mdaN^I&R(ZnRAH&@--{r!GL>2JCP{)<|p^3ID&cR+cd{P*kq_?%|r`k>bG2EFX zmq5e9OA2oX8aWH^tYas?Axf5L+?bhRp3P28L*hu_6-0$g1ZgW1tkFJ6Eh<+TN9YV* z^j}5|Nd}e#Tiu-WiU;ACoMDNIQ^>O$??P?oYZTF_0W_GX?~;ZG7Ccga3S^Z%A`Lr8 z4wD=pPe_sP7r1QFN`G1mI z2KNymH8l;4zW8;d2;T)#Uq2dc*xA4uK}X-aDwwt@GGpbmdt(s#Tm~m!)c(n1g3X9m z_AsHmm)br5GmpzfXs&bH02N?Ql0V{H4rXg?q<0?_8mSfHBs`z4|1p^==b}Hz%Q@%t zNB3OTPhuVY3vKfrm#PmJU>U z%;~gM@K^|7_HFwo%vBrle%tAg?X-UvqexKK&zy}R$ zQ(1a(%7|JY20Ejrz6-Ip>evjmfEK4ht;fH>#fQ5p3Tt9J`=`+z1`VRl885QJT(r~( zgZ^;j55qX(9q8ko3KzqT}F21|8HN=6u%Hh{)cxrKzrE^tWX_bsZ%;EEX<~t=IwC32B?$ z7t(ss(i{_orSfCu{QM>RmAkp%Gnvf6DD|WTC^&jXw!#D#QfjDuqGt7HVL4aJ%#%s- zW4n?x8Q575{5Bbg-NQZCCh1|ZP{@Y+{+H+(X~O>a#}dEbck}XIvi}oQ>~vu2Qq*7# zP5}jBEO}qhKEZw?i(`5!Sa#!flo%4?*;V@(HDWanjtt0q(-|k*TG6eN>{g}s*Cow* zHowN{@;v`UD;+tES5Q$ofgbP55HrVhd&D54@7FI;crH|#@)^(h>GU*0#{jjUQgqUB z4f)kVfwld;_*0)ufucjYPFkiJwPpw@f$4Pu)KMEhPDZsX5UqyOFVJ7|n91Z%Ao6;R z7+F5xJ_^|y%ZDij5uf3BcR#A%ZYBF1pPsHrpZ!YRex*umHG5v}N%tg{4Pmk`ozb=` zaTQ^W>}{q#kZ_SoH1gAo z+6sV(X8avzR7Bp!Z$!(>B;(d`aw-d>dS68YEB2$?pQXkak`~kqlB5PoD~SnIxHiTp z){LYg!xRzX`NR_TW!VDFG)2X(>v^#u4j=kq2{*H_3YOWH)Mj(L=)fU73Zi6?#($gKOzb!GB!W{CVL`-XBAcm3v<9@q^u$nvcpuo6C* zTx)R{Ok*-$?ev>r;G%3N|NVg3*J4j6=jd3LO@@?WBBVh<+J#GGBU5R*EBMP~YEbl{ z_-hqf&raw*rY>M&?X+)rG-viNM=Z7in~|~#Lz;hw5cT>S1={NIl=G?9wKbZ#u>$JW z$P^sZ=&XJ$;`}|I(Ty3fb&e3abw2Hifb@Z01!bju7eMkmTB8xz?Tnz+cxYFzAB*bI zqx!@{A>ybdpoES~%7-WZNvCAgbQ#+|-fRP zd)q!Gxxj5gNhPgDbOCJ`IY8%^)AmFP5B0gK_mZuha*3Z^uP+8g?rL6k#`WCFrRD{~ z%ircA?D50Wr}2f%ER&%p2vc=!g%ov?e^S&b%U5PvYrz0g(ha8gl(itg+gO9P9L(#h zfKE!OT+~v>LNnp0Ea|L7KU(G@xu__#a=NZkYeAQT|1szu$$6k~*X~nog4eBFa3kL- z4nk_#aNe3K#qEWL?;zY7O~~{e8=+w70fS&XOBj5NeuDFSN@W7mxRTb#O^*FHq}DBP z*m3H^M8c$N)uAPu7F~UXZSGv2w785IH@Y9?1g5LwoY0W5o&c$ zD0QIc4k_6CcK3AEyNv@e`!fg6=ULIL^;_lox0`P5%Y-)9HsR(XUraA8vw^4q-*agP za(NXb{JDPwA+GYGSIKE|Xy56eLFq~TYFBgxz?M7zH=2c=9(azYMJs%Z> z1JbB`8g_b^E_42xKJ$;@q^hdk3dAeLMW=C@lq(CRIqvp2bC@Wcp0oQIAHY@y#Q5#> z3s)D0Xew_gvS!^hPO$$)F+e!s_3y|^(`)F_s|MYYVeJb!zjGISoR%r*91XOrF>SBa z>xV8IXMYL#jb>f8r3E*jLbNg=_P&?DlRkYe1)7fuH1~KENMeyfvLKv4xP5XqY;><3 z3%xW-L7pVqY(acC8zHPNuiyx`8R%aBdHgQ~G|t4VuA!6QQKn-4do0}=w6JqqSlqSo zvKGkib$D4$6%<~?z|1PQm?G2_@}hhiXo=*%c)7KxP_s9XVBXbgN$2it3R5T&qOw%_ zN$4f?Bc)!h|02K1g6rnakT&xh>;!IGMW}uXejy0V7#-}g4F9kvz7eD9)QjiL%YGBQ zj?%amv$!Z6T}nkh6g};tBNkfE=^=1YbD(>~*xb$RcIp#;E6R%XaL=Tb3s7+cu>LwJYuBnfI41FjBp>tkVYk z9+P9N;%?`mv4}e^dyhA&OWs|UiRP~v*Nu+O^GN4LYV7adQz2SAvYFgez?dz055=Bj zGwyhrn!oswy`3j}ZAR+EapE5PKb9;;iMSZB!t@cLkq7N^Td?cvB=a*9b7_kc((p*> z2LCBpTxSAuWVo%TEB4;bEf;UP6@#~+I#8eRKF{BG%1%MKL{L{2%_&Yx;Y%`-u?7yF1cZyqKVj15d za1wv-UAhdEmH%lN)K@KItM^?W3CabFkF0wCP8!5&+->Kz(e1vb(~Pm_?#8(B=^qA` zg%;43EhdW+>Ydn(I(>0^X4QFR@Obh=mOB>px;^XtvbU!q4Hq}mKOkUuZRd)<5&C!1tB92_ofL7G&3Zj@Id8Oaz6HJPJ&Xk`|JzJZue*7f z|JTZDNH^;W)OKQ>rqZ8ql%M3t@WL1Jo-EJII>(V5fCn1VMU+S3JKqL4Y_v!YuW&?) z3!n?~aqS0*2?ZG-e4%Hma+u(imwpYh&$FE{B36RMmqast{WLJ+F zC5JOyULGD@UmQp1@}sP%z1Y#?YY4b9A1ClCRJhJsR{4gr(j74%V3N9nt5ujSI@$y@ zJ^JTkj;yRJA<=*}S`9+x{1>#K+x(tHFtvDa;CL?akHeul5H`S5WQaLGh+L;=HGVNY z-OHFmX-C3be{pek_G82bqv!hh??si*Y<}ziHu6JA*gAh5`dn~y{z<{n3bi7ZYz$XP z)R)O-NJ^j-j|-1dEqomISE?3eijbgz?u!OB3{hvzS1PkQ5IM$o1Zgt}a_y(eI#28y zt>?2qVDaQh4w~`Bx-~qL7fs{<&fwC>1#7MYGTHn6xE&qm>{Y9>6K)s9Ibn|Y%x&Lk zE;B6v%gV;g2WtiB_9R|Sw)l7r_Ll#5IQh?=&cnCU@fF{BT#+`b*QV){ldf25ULP5t zcS(AjTD?G1+u}yF_Mk2RUv8RQD3Yj3XZo1~SS?kNWb4w|8XVF}ch^>A9Vx5bT-C=C z10Pc|lta}J0}odSd;LfL{qFrIhVieArwK7bp{Un~tCO>bAI{yPd#H3tquar|dn?W7 zgcJO{MyzdNN4rFyNNe zwb}(e#J7XWNzPj}b23Y0-N@^6(?3Wc60WvESeI)?tQxLQiiE3_mDTH~ z^Q!ww%OdBI_N&Dg!+(7{vh=vF3QN==Q)c9g3~?XK@W_ap*=QmKyZq5g}bwlbA`H8w&t;-n^TwpnA zVba{hj!*|C!d&d`3>(&hm5m+3f|dMBrTu2TH-^2UViNNXkc0)e*@yxKmz|(zjo`X4 zn`Jn9f^@v+ujOqtizckl0&olx$eJxM*C}+9NGH?mhtfzv0%h0M$UDj3F*{zz)}B(* zcJq&;W@+*dy)qftP6%mLn?xy+)WsM*NUxA-Gb%we6IYyJN3!{VT37J_8%XTG=S3%C z%=kZ1n{*Gu%|ilnCWw4KDn6AalMG#a zdDtmb7z^lqp)sO=Mh@?yM#f1=tnnb-JHCnQ(7Vw!x_1g^hy z&mMjwSj>Vw(9HZP+Bk3O!cNks)S5q(kjf9OP*rRn4#Zxawk~UW(UJ#}I*RQ{nB$>q zQ^aiKu6|b_rsLA-8tj_+nj|Lnq4Qnn1#+Sld5|KBfrYPVsIn3J2IJzL!X!jy$2LPK z`QLPSp?O-oh!$8uDG#|-^rGM8xP`F{>t^_p1vfQ@)1mtC+VX+8j&D#R>Xm$z@(C;J z?|xJL47x4a=vm(|9p6wkS1>c~p>az^YwL1uRnUoJrt#OBdm@Gp)Z0xoLO3By zm!5xWK(k#5^UsDb#uL;)ZMnxSZGJL)XFX)?xeS8wqpUCf zy(=GYXQ_oR)4>!n8n5b0*Bpb6g*@~9OO zy~Nk+gYu)UK^n!0bOZhb&}9HDcujz7xn4q&=OV-CNZIfzcyVNQpd-E6Mu*CUNG;=X zQWL%!A0y1?S2Mj3UV0uT&($PEU%-GTkqt-YdUG3yCaFTxHn!$aChbY(+-4@wq9*W9PdgXU05Nx?GBSj34A#M1 zI&ZTmwsvBYhStN6(r~&{{)pCLZqdMZdfvt!YCg!MgQV!!>aJwL%g`BHCjjO$4}=@sZEt~@xVYCA#IH@Y46B?H@gtJ z=RU#@P+sYg_ploPN)~506u4yh+FVxFY>|DtgI6Wov1|0!5=#WCS^wLGOM)F-*c7CE{tSgRN#SF$oZMkmA)4#JGR`wPN%p>4ql;d=Ul}NrgT-1Fb93iiZEa}lA|xgkrVRBqjRr=*bp{Zig1~6p_r0USLx79^ z8o*_c4(gH9A!UNnJ8z*qNM0HelOH=I)LwS}+kL!Z33Vro+S6gob1CIDCbYi*oygJ16_ZIN`bmj7Qv%}|uIQt9{lwsUI zliK=oO`3WuUmlIU==G0Y2&{oILq4Q!hv2N$MK+C%3Kq$A6nT+z!I64StUe15#M$6_vY{ z(aO+DYDt7tMd!0YHd9T$wrm9btOu6?cHB_~_Kx%ejfddx>7A9>F*T#J(AxW0eQF$3 zdXo#QYbhp(PT>T}wgiK}YF}wg47D)HdG)A<(oi>nw7|B$Zz#`6Qf^vQrG3Wf2a86i zI2o%dD@9k<*JrKc9lk-X{qO&daD$TyJLzOd>!gn@<1r+&oA&q-CIL3Wa7E#6_p@;o zxTx`%<*^kuV|ANH`zAjbR)qEg);)3F!!2jeN>qJ+?pv8^8PI31-Eyqr*^j|3o6}5DTxA}H$1@w(c3iA`*?4KA>e8zv8PO|%Y z?uTXS20nNzFZ$}n=gKe9wr~~-P{Y;N_Fpz>Aqau&Bl3>5h@P2d;fp2nN)GclZR0Cy zpHRsxb|A3;SqXNb61}R++FXD8azciZ`QbxQxJbxg%CHB(Q3d~XZJZTSX?BB@Z_DxF z&K4z$s#N;XVl?J6Kcq#;nnL4vE_*WW;>ijf=!f+QxMjEe(axKmB5{09Mv@lfSPial zD5xdN3o3;*c=-;2Toty!2Z(1j4^ZmwKv!-LCh{+=MeIR^v&e<&^RD8hc0`HDXYtsA zQ4F{9N#&ghY!OSeBzpyFh1i9+fCWNlBk`DeeuG~c%NyrG4;6_aBH*jX-(`HhKaW%M zA%ZZ&DI=kS?uE7^~-$EruBJ))e~{Xf0nSi@;r`EGW>dC|Cc0zo+2B$_m5L)sl%zWwqfB80&+jRn7Ck zbmd4eh93lwFDnc)kgmo=jeqa1yn!{`@NpVRQm-IIBS-`lM?d4Ip9tmarqA|k;rRX& z)o7TS=0J!%TTQ@qOB$bUdM29`i%Dqv&&sLm$_Bx5F<8uuCr77wjFCy}o6Ss-j?G!I z%{|E=N3U53g)v9Q2XNANf|#=W;I$X4<5_vCA)lUW3g2#H5_H7p&LS^>{W5mR1`|!GMTl1&Omg@e~C?%BNiI7bCQL{MLIsGwTQR3;A;_z zzdywEBYWHYh2N$hH&|o8VNk&yvywG859&yWStdp-ncn3SU-|KRwg$|F|2SLeBZR&q zU~Og1Kp`HS92&hRz@Ech*?cp5TLqo?>9tH*Mv7PFqn8=0t2&irDJHeiySddeF9OC(WMiN zxfA87jxQpt<17D?#pH<;e7pVPSK}G6#78nU!;63ojNjEhu$a>!e>^+BMkwquq@}&>F;Nz*$_|nyn2tBvJw`v9v4eUnl{SKww}h{eWMzk#7rOwUNo!`^ znB65W)+Se7l}GCC0)AZU(Q=q<nX$>tieb}TUunIE_&U}7Pf{?m zLH8!wum;pcvd}mDs6?f$V50qYkYu~!?CE(EsK2_=tg`Jn{#3i|e^Mi-to*H@$HmeG znS{G+$UJ)S025u=Gkax=ddsvCh# z%x#y2rKMQtg9vu#<>lpoNPeW=MB6f}21LQi^AopN2=n3>we+W8yCEvMU9@sXN{=&gEd_V~;^rZBsEBw7E z`+i_9CO3(UV_eJc-Yav1jfPAhrlw7Blywkm%UrnPLgc}TEp9UyGpLvFUveFFdQ--E zevMYr>Ca7bM*>DwTjuOc-oOq=IPC@}KZvvt9%B}2V1e#?Vd$!)vc2qBtI*R5abz8u z%WFl6VwLlWK(?fCENBRz(IZWg7PX00bh=ZU6uP literal 0 HcmV?d00001 diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/loc/en-us.js b/SharePoint/SharePoint/src/webparts/pdfviewer/loc/en-us.js new file mode 100644 index 0000000..3b25e74 --- /dev/null +++ b/SharePoint/SharePoint/src/webparts/pdfviewer/loc/en-us.js @@ -0,0 +1,16 @@ +define([], function() { + return { + "PropertyPaneDescription": "Description", + "BasicGroupName": "Group Name", + "DescriptionFieldLabel": "Description Field", + "AppLocalEnvironmentSharePoint": "The app is running on your local environment as SharePoint web part", + "AppLocalEnvironmentTeams": "The app is running on your local environment as Microsoft Teams app", + "AppLocalEnvironmentOffice": "The app is running on your local environment in office.com", + "AppLocalEnvironmentOutlook": "The app is running on your local environment in Outlook", + "AppSharePointEnvironment": "The app is running on SharePoint page", + "AppTeamsTabEnvironment": "The app is running in Microsoft Teams", + "AppOfficeEnvironment": "The app is running in office.com", + "AppOutlookEnvironment": "The app is running in Outlook", + "UnknownEnvironment": "The app is running in an unknown environment" + } +}); \ No newline at end of file diff --git a/SharePoint/SharePoint/src/webparts/pdfviewer/loc/mystrings.d.ts b/SharePoint/SharePoint/src/webparts/pdfviewer/loc/mystrings.d.ts new file mode 100644 index 0000000..3807635 --- /dev/null +++ b/SharePoint/SharePoint/src/webparts/pdfviewer/loc/mystrings.d.ts @@ -0,0 +1,19 @@ +declare interface IPdfviewerWebPartStrings { + PropertyPaneDescription: string; + BasicGroupName: string; + DescriptionFieldLabel: string; + AppLocalEnvironmentSharePoint: string; + AppLocalEnvironmentTeams: string; + AppLocalEnvironmentOffice: string; + AppLocalEnvironmentOutlook: string; + AppSharePointEnvironment: string; + AppTeamsTabEnvironment: string; + AppOfficeEnvironment: string; + AppOutlookEnvironment: string; + UnknownEnvironment: string; +} + +declare module 'PdfviewerWebPartStrings' { + const strings: IPdfviewerWebPartStrings; + export = strings; +} diff --git a/SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_color.png b/SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_color.png new file mode 100644 index 0000000000000000000000000000000000000000..0e1f764fa8df4791a61c71b4f011c26f9083ee52 GIT binary patch literal 10248 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 KtK_^>#Qy@$+e&%> literal 0 HcmV?d00001 diff --git a/SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_outline.png b/SharePoint/SharePoint/teams/87887a8b-fa43-424d-9383-5e5a2a782bfd_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..e8cb4b6ba4f726d47a2e274f16b6069b9a8041cc GIT binary patch literal 249 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz&H|6fVg?3oVGw3ym^DWND9BhG z%|CHbgX^da?eHs6`1kLARhjOac zf3;y1Iq~M{LLS3g_M2bU{+PBvomV=FH7$YTy5I%1<5B$=?>3fqI5P%5iajq7)W9SX p;gpazd1JnvZNlx8HB0WjVJ`J~Q+P@%pA+aZ22WQ%mvv4FO#n^cR9FB2 literal 0 HcmV?d00001 diff --git a/SharePoint/SharePoint/tsconfig.json b/SharePoint/SharePoint/tsconfig.json new file mode 100644 index 0000000..c4cd392 --- /dev/null +++ b/SharePoint/SharePoint/tsconfig.json @@ -0,0 +1,35 @@ +{ + "extends": "./node_modules/@microsoft/rush-stack-compiler-4.7/includes/tsconfig-web.json", + "compilerOptions": { + "target": "es5", + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "jsx": "react", + "declaration": true, + "sourceMap": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "outDir": "lib", + "inlineSources": false, + "noImplicitAny": true, + + "typeRoots": [ + "./node_modules/@types", + "./node_modules/@microsoft" + ], + "types": [ + "webpack-env" + ], + "lib": [ + "es5", + "dom", + "es2015.collection", + "es2015.promise" + ] + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ] +}