diff --git a/.github/workflows/jekyll_gh_pages.yml b/.github/workflows/jekyll_gh_pages.yml index 2a9708a..6bd9014 100644 --- a/.github/workflows/jekyll_gh_pages.yml +++ b/.github/workflows/jekyll_gh_pages.yml @@ -4,7 +4,7 @@ name: Deploy SharePoint Integration Documentation on: # Runs on pushes targeting the default branch push: - branches: ["1.x"] + branches: ['1.x'] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -18,7 +18,7 @@ permissions: # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency: - group: "pages" + group: 'pages' cancel-in-progress: false jobs: @@ -27,12 +27,19 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@v3 + - name: Setup Pages uses: actions/configure-pages@v3 + + - name: Move LaserficheSharePointIntegrationAppManifest.json + run: cp ./UserDocuments/LaserficheSharePointIntegrationAppManifest.json ./jekyll_files/docs/assets/LaserficheSharePointIntegrationAppManifest.json + - name: Build with Jekyll uses: actions/jekyll-build-pages@v1 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 962fc8b..f4c1255 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -34,10 +34,10 @@ jobs: message: Workflow run ${{github.server_url}}/${{github.repository}}/actions/runs/${{ github.run_id}} - name: replace config/package-solution.json version - run: sed -i 's/VERSION_TO_UPDATE/${{env.fullVersion}}/g' config/package-solution.json + run: sed -i 's/"1.0.0.0"/"${{env.fullVersion}}"/g' config/package-solution.json - name: replace package.json version - run: sed -i 's/VERSION_TO_UPDATE/${{env.fullVersion}}/g' package.json + run: sed -i 's/"1.0.0.0"/"${{env.fullVersion}}"/g' package.json - name: Install dependencies run: npm ci diff --git a/config/package-solution.json b/config/package-solution.json index 4bb6d13..c386fc2 100644 --- a/config/package-solution.json +++ b/config/package-solution.json @@ -3,7 +3,7 @@ "solution": { "name": "Laserfiche Sharepoint Online Integration", "id": "9d9d4fa7-bbf4-489a-acd5-0e1709d40e8b", - "version": "VERSION_TO_UPDATE", + "version": "1.0.0.0", "includeClientSideAssets": true, "title": "Laserfiche SharePoint Online Integration", "iconPath": "assets/laserfiche-logo-96.png", @@ -20,7 +20,7 @@ "title": "Save to Laserfiche", "description": "Allows user to save SharePoint documents to their Laserfiche repository, with admin-configured metadata mappings.", "id": "9c2b7b96-fb6e-4c42-9676-9d434992110f", - "version": "VERSION_TO_UPDATE", + "version": "1.0.0.0", "assets": { "elementManifests": ["elements.xml"] } diff --git a/jekyll_files/docs/admin-documentation/register-app-in-laserfiche.md b/jekyll_files/docs/admin-documentation/register-app-in-laserfiche.md index 0b30eeb..0b26ff3 100644 --- a/jekyll_files/docs/admin-documentation/register-app-in-laserfiche.md +++ b/jekyll_files/docs/admin-documentation/register-app-in-laserfiche.md @@ -15,7 +15,7 @@ parent: Laserfiche SharePoint Integration Administration Guide 1. Open the [Developer Console](https://developer.laserfiche.com/developer-console.html). -1. Attempt to Create a New App from Manifest, and upload the manifest provided [here](../assets/manifest.json). +1. Attempt to Create a New App from Manifest, and upload the manifest provided [here](../assets/LaserficheSharePointIntegrationAppManifest.json). 1. If the attempt fails because an app with that client ID already exists, find the app with that client id by opening [this url](https://app.laserfiche.com/devconsole/apps/8ee987ea-a0b1-4ca2-85c4-a79b335cd214/config) in a new tab. diff --git a/jekyll_files/docs/assets/manifest.json b/jekyll_files/docs/assets/manifest.json deleted file mode 100644 index 4d1c5d2..0000000 --- a/jekyll_files/docs/assets/manifest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "clientId": "8ee987ea-a0b1-4ca2-85c4-a79b335cd214", - "name": "Laserfiche SharePoint Integration", - "description": "View your Laserfiche repository and send SharePoint documents to Laserfiche from directly within SharePoint.", - "type": "SPA", - "expiresInMinutes": 60, - "scopes": [ - "repository.Write", - "repository.Read" - ], - "privacyPolicyUrl": "https://www.laserfiche.com/legal/privacy/", - "documentationUrl": "https://laserfiche.github.io/laserfiche-sharepoint-integration/", - "termsOfServiceUrl": "https://www.laserfiche.com/legal/terms-of-use/" -} diff --git a/package-lock.json b/package-lock.json index 959131e..f58d790 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "laserfiche-sharepoint-integration", - "version": "VERSION_TO_UPDATE", + "version": "1.0.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "laserfiche-sharepoint-integration", - "version": "VERSION_TO_UPDATE", + "version": "1.0.0.0", "license": "MIT", "dependencies": { "@laserfiche/lf-repository-api-client": "^1.0.12", diff --git a/package.json b/package.json index bcf1a64..0800eb9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "laserfiche-sharepoint-integration", - "version": "VERSION_TO_UPDATE", + "version": "1.0.0.0", "private": true, "main": "lib/index.js", "license": "MIT", diff --git a/src/extensions/savetoLaserfiche/SavetoLaserficheCommandSet.tsx b/src/extensions/savetoLaserfiche/SavetoLaserficheCommandSet.tsx index 2daa1a5..07f0ecd 100644 --- a/src/extensions/savetoLaserfiche/SavetoLaserficheCommandSet.tsx +++ b/src/extensions/savetoLaserfiche/SavetoLaserficheCommandSet.tsx @@ -10,7 +10,7 @@ import { import { PathUtils } from '@laserfiche/lf-js-utils'; import { CreateConfigurations } from '../../Utils/CreateConfigurations'; import { getSPListURL } from '../../Utils/Funcs'; -import { SP_LOCAL_STORAGE_KEY } from '../../webparts/constants'; +import { LASERFICHE_SIGNIN_PAGE_NAME, SP_LOCAL_STORAGE_KEY } from '../../webparts/constants'; /** * If your command set uses the ClientSideComponentProperties JSON input, @@ -23,10 +23,6 @@ export interface ISendToLfCommandSetProperties { sampleTextTwo: string; } -enum SpWebPartNames { - 'LaserficheSignIn' = 'LaserficheSignIn', -} - const LOG_SOURCE = 'SendToLfCommandSet'; export default class SendToLfCommandSet extends BaseListViewCommandSet { @@ -112,7 +108,7 @@ export default class SendToLfCommandSet extends BaseListViewCommandSet { + try { + const res = await fetch( + `${getSPListURL(props.context, 'Site Pages')}/items`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + } + ); + const sitePages = await res.json(); + for (let o = 0; o < sitePages.value.length; o++) { + const pageName = sitePages.value[o].Title; + if (pageName === LASERFICHE_SIGNIN_PAGE_NAME) { + return true; + } + } + } catch (error) { + console.warn(`Unable to determine if a SharePoint Page with name ${LASERFICHE_SIGNIN_PAGE_NAME} exists.`) + return false; + } + return false; + } + + async function clickLogin(): Promise { const url = props.context.pageContext.web.absoluteUrl + '/SitePages/LaserficheSignIn.aspx?autologin'; + const hasSignIn = await pageConfigurationCheck(); + if (!hasSignIn) { + const mes = ( + { + setMessageErrorModal(undefined); + }} + /> + ); + setMessageErrorModal(mes); + return; + } const loginWindow = window.open(url, 'loginWindow', 'popup'); loginWindow.resizeTo(800, 600); window.addEventListener('message', (event) => { diff --git a/src/webparts/LaserficheRepositoryAccessWebPart/components/RepositoryViewWebPart.tsx b/src/webparts/LaserficheRepositoryAccessWebPart/components/RepositoryViewWebPart.tsx index 5fd567d..64c0c83 100644 --- a/src/webparts/LaserficheRepositoryAccessWebPart/components/RepositoryViewWebPart.tsx +++ b/src/webparts/LaserficheRepositoryAccessWebPart/components/RepositoryViewWebPart.tsx @@ -465,7 +465,7 @@ function ImportFileModal(props: { } const extension = PathUtils.getCleanedExtension(fileData.name); const renamedFile = new File([fileData], fileName + extension); - const fileContainsBacklash = fileName.includes('\\'); + const fileContainsBackslash = fileName.includes('\\'); try { const entryWithPathExists = await props.repoClient.entriesClient.getEntryByPath({ @@ -493,7 +493,7 @@ function ImportFileModal(props: { throw err; } } - if (fileContainsBacklash) { + if (fileContainsBackslash) { setFileUploadPercentage(0); setImportFileValidationMessage(fileNameWithBacklash); return; @@ -725,7 +725,8 @@ function CreateFolderModal(props: { const createNewFolderAsync: () => Promise = async () => { if (folderName) { - if (/^[\\\\]*$/.test(folderName)) { + const fileContainsBackslash = folderName.includes('\\'); + if (fileContainsBackslash) { setCreateFolderNameValidationMessage(folderBackslashNameValidation); } else { setCreateFolderNameValidationMessage(undefined); diff --git a/src/webparts/constants.ts b/src/webparts/constants.ts index dc84dc0..44f0a1b 100644 --- a/src/webparts/constants.ts +++ b/src/webparts/constants.ts @@ -5,6 +5,7 @@ export const MANAGE_MAPPING = 'ManageMapping'; export const MANAGE_CONFIGURATIONS = 'ManageConfigurations'; export const LOGIN_WINDOW_SUCCESS = 'loginWindowSuccess'; +export const LASERFICHE_SIGNIN_PAGE_NAME = 'LaserficheSignIn'; export const SP_LOCAL_STORAGE_KEY = 'spdocdata'; export const SPDEVMODE_LOCAL_STORAGE_KEY = 'spDevMode'; diff --git a/src/webparts/laserficheAdminConfiguration/components/LaserficheAdminConfiguration.tsx b/src/webparts/laserficheAdminConfiguration/components/LaserficheAdminConfiguration.tsx index a8244e8..8870235 100644 --- a/src/webparts/laserficheAdminConfiguration/components/LaserficheAdminConfiguration.tsx +++ b/src/webparts/laserficheAdminConfiguration/components/LaserficheAdminConfiguration.tsx @@ -11,6 +11,7 @@ import EditManageConfiguration from './EditManageConfiguration/EditManageConfigu import AddNewManageConfiguration from './AddNewManageConfiguration/AddNewManageConfiguration'; import { clientId, + LASERFICHE_SIGNIN_PAGE_NAME, LF_INDIGO_PINK_CSS_URL, LF_MS_OFFICE_LITE_CSS_URL, LF_UI_COMPONENTS_URL, @@ -25,7 +26,7 @@ import { import { RepositoryClientExInternal } from '../../../repository-client/repository-client'; import { IRepositoryApiClientExInternal } from '../../../repository-client/repository-client-types'; import { SPComponentLoader } from '@microsoft/sp-loader'; -import { getRegion } from '../../../Utils/Funcs'; +import { getRegion, getSPListURL } from '../../../Utils/Funcs'; import styles from './LaserficheAdminConfiguration.module.scss'; import { SPPermission } from '@microsoft/sp-page-context'; import { MessageDialog } from '../../../extensions/savetoLaserfiche/CommonDialogs'; @@ -33,6 +34,7 @@ import { MessageDialog } from '../../../extensions/savetoLaserfiche/CommonDialog const YOU_DO_NOT_HAVE_RIGHTS_FOR_ADMIN_CONFIG_PLEASE_CONTACT_ADMIN = 'You do not have the necessary rights to view or edit the Laserfiche SharePoint Integration configuration. Please contact your administrator for help.'; +const needLaserficheSignInPage = `Missing "${LASERFICHE_SIGNIN_PAGE_NAME}" SharePoint page. Please refer to the Adding App to SharePoint Site topic in the administration guide for configuration steps.`; export default function LaserficheAdminConfiguration( props: ILaserficheAdminConfigurationProps ): JSX.Element { @@ -113,10 +115,50 @@ export default function LaserficheAdminConfiguration( void initializeComponentAsync(); }, []); - function clickLogin(): void { + async function pageConfigurationCheck(): Promise { + try { + const res = await fetch( + `${getSPListURL(props.context, 'Site Pages')}/items`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + } + ); + const sitePages = await res.json(); + for (let o = 0; o < sitePages.value.length; o++) { + const pageName = sitePages.value[o].Title; + if (pageName === LASERFICHE_SIGNIN_PAGE_NAME) { + return true; + } + } + } catch (error) { + console.warn(`Unable to determine if a SharePoint Page with name ${LASERFICHE_SIGNIN_PAGE_NAME} exists.`) + return false; + } + return false; + } + + async function clickLogin(): Promise { const url = props.context.pageContext.web.absoluteUrl + '/SitePages/LaserficheSignIn.aspx?autologin'; + const hasSignIn = await pageConfigurationCheck(); + if (!hasSignIn) { + const mes = ( + { + setMessageErrorModal(undefined); + }} + /> + ); + setMessageErrorModal(mes); + return; + } const loginWindow = window.open(url, 'loginWindow', 'popup'); loginWindow.resizeTo(800, 600); window.addEventListener('message', (event) => { diff --git a/src/webparts/sendToLaserficheLoginComponent/components/SendToLaserficheLoginComponent.tsx b/src/webparts/sendToLaserficheLoginComponent/components/SendToLaserficheLoginComponent.tsx index 9a184fd..c77502c 100644 --- a/src/webparts/sendToLaserficheLoginComponent/components/SendToLaserficheLoginComponent.tsx +++ b/src/webparts/sendToLaserficheLoginComponent/components/SendToLaserficheLoginComponent.tsx @@ -8,6 +8,7 @@ import { } from '@laserfiche/types-lf-ui-components'; import { clientId, + LASERFICHE_SIGNIN_PAGE_NAME, LF_INDIGO_PINK_CSS_URL, LF_MS_OFFICE_LITE_CSS_URL, LF_UI_COMPONENTS_URL, @@ -19,7 +20,7 @@ import { NgElement, WithProperties } from '@angular/elements'; import { ISendToLaserficheLoginComponentProps } from './ISendToLaserficheLoginComponentProps'; import { ISPDocumentData } from '../../../Utils/Types'; import SaveToLaserficheCustomDialog from '../../../extensions/savetoLaserfiche/SaveToLaserficheDialog'; -import { getEntryWebAccessUrl, getRegion } from '../../../Utils/Funcs'; +import { getEntryWebAccessUrl, getRegion, getSPListURL } from '../../../Utils/Funcs'; import styles from './SendToLaserficheLoginComponent.module.scss'; import { MessageDialog } from '../../../extensions/savetoLaserfiche/CommonDialogs'; declare global { @@ -39,6 +40,7 @@ const YOU_MUST_BE_CLOUD_USER_TO_USE_WEB_PART = 'You must be a currently licensed Laserfiche Cloud user to use this web part.'; const FOR_MORE_INFO_VISIT = 'For more information visit'; +const needLaserficheSignInPage = `Missing ${LASERFICHE_SIGNIN_PAGE_NAME} SharePoint page. Please refer to the Adding App to SharePoint Site topic in the administration guide for configuration steps.`; export default function SendToLaserficheLoginComponent( props: ISendToLaserficheLoginComponentProps ): JSX.Element { @@ -305,10 +307,50 @@ export default function SendToLaserficheLoginComponent( Navigation.navigate(path, true); } - function clickLogin(): void { + async function pageConfigurationCheck(): Promise { + try { + const res = await fetch( + `${getSPListURL(props.context, 'Site Pages')}/items`, + { + method: 'GET', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + } + ); + const sitePages = await res.json(); + for (let o = 0; o < sitePages.value.length; o++) { + const pageName = sitePages.value[o].Title; + if (pageName === LASERFICHE_SIGNIN_PAGE_NAME) { + return true; + } + } + } catch (error) { + console.warn(`Unable to determine if a SharePoint Page with name ${LASERFICHE_SIGNIN_PAGE_NAME} exists.`) + return false; + } + return false; + } + + async function clickLogin(): Promise { const url = props.context.pageContext.web.absoluteUrl + '/SitePages/LaserficheSignIn.aspx?autologin'; + const hasSignIn = await pageConfigurationCheck(); + if (!hasSignIn) { + const mes = ( + { + setMessageErrorModal(undefined); + }} + /> + ); + setMessageErrorModal(mes); + return; + } const loginWindow = window.open(url, 'loginWindow', 'popup'); loginWindow.resizeTo(800, 600);