├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json └── index.html ├── src ├── components │ ├── breadcrumbs-items.js │ ├── FilesAppLayout │ │ └── FilesAppLayout.js │ ├── AppBar │ │ └── AppBar.js │ ├── TableListFiles │ │ └── TableListFiles.js │ └── UploadFileCard │ │ └── UploadFileCard.js ├── setupTests.js ├── index.css ├── reportWebVitals.js ├── index.js ├── App.js ├── screen │ └── Main │ │ ├── Main.css │ │ └── Main.js └── logo.svg ├── amplify ├── backend │ ├── tags.json │ ├── tsconfig.json │ ├── storage │ │ └── slgfiles │ │ │ ├── override.ts │ │ │ └── cli-inputs.json │ ├── predictions │ │ ├── interpretText99e26fde │ │ │ ├── parameters.json │ │ │ └── interpretText99e26fde-template.json │ │ └── identifyText77dd4f2a │ │ │ ├── parameters.json │ │ │ └── identifyText77dd4f2a-template.json │ ├── package.json │ ├── types │ │ └── amplify-dependent-resources-ref.d.ts │ ├── hosting │ │ └── amplifyhosting │ │ │ └── amplifyhosting-template.json │ ├── backend-config.json │ └── auth │ │ └── slgfiles71a417f4 │ │ └── cli-inputs.json ├── README.md ├── .config │ └── project-config.json ├── hooks │ ├── README.md │ ├── post-push.sh.sample │ └── pre-push.js.sample └── cli.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── package.json ├── CONTRIBUTING.md ├── README.md └── .gitignore /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/online-document-manager-amplify/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/online-document-manager-amplify/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/online-document-manager-amplify/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/components/breadcrumbs-items.js: -------------------------------------------------------------------------------- 1 | export const defaultBreadcrumbs = [ 2 | { 3 | text: 'Document manager', 4 | href: '#', 5 | }, 6 | ]; -------------------------------------------------------------------------------- /amplify/backend/tags.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Key": "user:Stack", 4 | "Value": "{project-env}" 5 | }, 6 | { 7 | "Key": "user:Application", 8 | "Value": "{project-name}" 9 | } 10 | ] -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /amplify/backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "module": "commonjs", 5 | "strict": false, 6 | "esModuleInterop": true, 7 | "skipLibCheck": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "outDir": "build" 10 | } 11 | } -------------------------------------------------------------------------------- /amplify/backend/storage/slgfiles/override.ts: -------------------------------------------------------------------------------- 1 | import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper'; 2 | 3 | export function override(resources: AmplifyS3ResourceTemplate) { 4 | resources.s3Bucket.accelerateConfiguration = { 5 | accelerationStatus: 'Enabled' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /amplify/backend/storage/slgfiles/cli-inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "slgfiles", 3 | "policyUUID": "45b50b70", 4 | "bucketName": "slgfiles-content-s3", 5 | "storageAccess": "auth", 6 | "guestAccess": [], 7 | "authAccess": [ 8 | "CREATE_AND_UPDATE", 9 | "READ", 10 | "DELETE" 11 | ], 12 | "triggerFunction": "NONE", 13 | "groupAccess": {} 14 | } -------------------------------------------------------------------------------- /amplify/backend/predictions/interpretText99e26fde/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "interpretText99e26fde", 3 | "interpretPolicyName": "interpretPolicy99e26fde", 4 | "authRoleName": { 5 | "Ref": "AuthRoleName" 6 | }, 7 | "unauthRoleName": { 8 | "Ref": "UnauthRoleName" 9 | }, 10 | "interpretType": "interpretText", 11 | "type": "ALL", 12 | "access": "auth" 13 | } -------------------------------------------------------------------------------- /amplify/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Amplify CLI 2 | This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli). 3 | 4 | Helpful resources: 5 | - Amplify documentation: https://docs.amplify.aws 6 | - Amplify CLI documentation: https://docs.amplify.aws/cli 7 | - More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files 8 | - Join Amplify's community: https://amplify.aws/community/ 9 | -------------------------------------------------------------------------------- /amplify/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "overrides-dependencies", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "build": "tsc", 7 | "watch": "tsc -w", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "dependencies": { 11 | "@aws-amplify/cli-extensibility-helper": "^2.0.0" 12 | }, 13 | "devDependencies": { 14 | "typescript": "^4.2.4" 15 | } 16 | } -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "slgfiles", 3 | "version": "3.1", 4 | "frontend": "javascript", 5 | "javascript": { 6 | "framework": "react", 7 | "config": { 8 | "SourceDir": "src", 9 | "DistributionDir": "build", 10 | "BuildCommand": "npm run-script build", 11 | "StartCommand": "npm run-script start" 12 | } 13 | }, 14 | "providers": [ 15 | "awscloudformation" 16 | ] 17 | } -------------------------------------------------------------------------------- /amplify/hooks/README.md: -------------------------------------------------------------------------------- 1 | # Command Hooks 2 | 3 | Command hooks can be used to run custom scripts upon Amplify CLI lifecycle events like pre-push, post-add-function, etc. 4 | 5 | To get started, add your script files based on the expected naming convention in this directory. 6 | 7 | Learn more about the script file naming convention, hook parameters, third party dependencies, and advanced configurations at https://docs.amplify.aws/cli/usage/command-hooks 8 | -------------------------------------------------------------------------------- /amplify/backend/predictions/identifyText77dd4f2a/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "identifyText77dd4f2a", 3 | "identifyPolicyName": "identifyPolicy77dd4f2a", 4 | "authRoleName": { 5 | "Ref": "AuthRoleName" 6 | }, 7 | "unauthRoleName": { 8 | "Ref": "UnauthRoleName" 9 | }, 10 | "adminAuthProtected": "DISALLOW", 11 | "adminGuestProtected": "DISALLOW", 12 | "identifyType": "identifyText", 13 | "identifyDoc": true, 14 | "access": "auth", 15 | "format": "ALL" 16 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | const root = ReactDOM.createRoot(document.getElementById('root')); 8 | root.render( 9 | 10 | 11 | 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Online Document Manager Amplify", 3 | "name": "AWS Solution", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import {withAuthenticator} from '@aws-amplify/ui-react'; 2 | import '@aws-amplify/ui-react/styles.css'; 3 | 4 | import { Amplify, Auth } from 'aws-amplify'; 5 | import awsconfig from './aws-exports'; 6 | 7 | import {HashRouter, Route, Routes} from "react-router-dom"; 8 | import Main from "./screen/Main/Main"; 9 | 10 | Amplify.configure(awsconfig); 11 | 12 | function App() { 13 | return ( 14 | 15 | 16 | }/> 17 | }/> 18 | 19 | 20 | 21 | ); 22 | } 23 | 24 | export default withAuthenticator(App); 25 | // export default App; 26 | -------------------------------------------------------------------------------- /src/screen/Main/Main.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /amplify/hooks/post-push.sh.sample: -------------------------------------------------------------------------------- 1 | # This is a sample hook script created by Amplify CLI. 2 | # To start using this post-push hook please change the filename: 3 | # post-push.sh.sample -> post-push.sh 4 | # 5 | # learn more: https://docs.amplify.aws/cli/usage/command-hooks 6 | 7 | if [ -z "$(which jq)" ]; then 8 | echo "Please install jq to run the sample script." 9 | exit 0 10 | fi 11 | 12 | parameters=`cat` 13 | error=$(jq -r '.error // empty' <<< "$parameters") 14 | data=$(jq -r '.data' <<< "$parameters") 15 | 16 | # 17 | # Write code here: 18 | # 19 | if [ ! -z "$error" ]; then 20 | echo "Amplify CLI emitted an error:" $(jq -r '.message' <<< "$error") 21 | exit 0 22 | fi 23 | echo "project root path:" $(pwd); 24 | echo "Amplify CLI command:" $(jq -r '.amplify | .command' <<< "$data") -------------------------------------------------------------------------------- /src/components/FilesAppLayout/FilesAppLayout.js: -------------------------------------------------------------------------------- 1 | import Header from "@cloudscape-design/components/header"; 2 | import {AppLayout, BreadcrumbGroup, ContentLayout} from "@cloudscape-design/components"; 3 | 4 | export default function FilesAppLayout(props) { 5 | 6 | return ( 7 | } 11 | content={ 12 | 17 | { props.title } 18 | 19 | } 20 | > 21 | { props.children } 22 | 23 | 24 | }/> 25 | 26 | ); 27 | } -------------------------------------------------------------------------------- /amplify/backend/types/amplify-dependent-resources-ref.d.ts: -------------------------------------------------------------------------------- 1 | export type AmplifyDependentResourcesAttributes = { 2 | "auth": { 3 | "slgfiles71a417f4": { 4 | "IdentityPoolId": "string", 5 | "IdentityPoolName": "string", 6 | "UserPoolId": "string", 7 | "UserPoolArn": "string", 8 | "UserPoolName": "string", 9 | "AppClientIDWeb": "string", 10 | "AppClientID": "string" 11 | } 12 | }, 13 | "storage": { 14 | "slgfiles": { 15 | "BucketName": "string", 16 | "Region": "string" 17 | } 18 | }, 19 | "predictions": { 20 | "identifyText77dd4f2a": { 21 | "region": "string", 22 | "format": "string" 23 | }, 24 | "interpretText99e26fde": { 25 | "region": "string", 26 | "type": "string" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /amplify/hooks/pre-push.js.sample: -------------------------------------------------------------------------------- 1 | /** 2 | * This is a sample hook script created by Amplify CLI. 3 | * To start using this pre-push hook please change the filename: 4 | * pre-push.js.sample -> pre-push.js 5 | * 6 | * learn more: https://docs.amplify.aws/cli/usage/command-hooks 7 | */ 8 | 9 | /** 10 | * @param data { { amplify: { environment: { envName: string, projectPath: string, defaultEditor: string }, command: string, subCommand: string, argv: string[] } } } 11 | * @param error { { message: string, stack: string } } 12 | */ 13 | const hookHandler = async (data, error) => { 14 | // TODO write your hook handler here 15 | }; 16 | 17 | const getParameters = async () => { 18 | const fs = require("fs"); 19 | return JSON.parse(fs.readFileSync(0, { encoding: "utf8" })); 20 | }; 21 | 22 | getParameters() 23 | .then((event) => hookHandler(event.data, event.error)) 24 | .catch((err) => { 25 | console.error(err); 26 | process.exitCode = 1; 27 | }); 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /amplify/backend/hosting/amplifyhosting/amplifyhosting-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"8.3.1\",\"stackType\":\"hosting-amplifyhosting\",\"metadata\":{}}", 4 | "Parameters": { 5 | "env": { 6 | "Type": "String" 7 | }, 8 | "appId": { 9 | "Type": "String" 10 | }, 11 | "type": { 12 | "Type": "String" 13 | } 14 | }, 15 | "Conditions": { 16 | "isManual": { 17 | "Fn::Equals": [ 18 | { 19 | "Ref": "type" 20 | }, 21 | "manual" 22 | ] 23 | } 24 | }, 25 | "Resources": { 26 | "AmplifyBranch": { 27 | "Condition": "isManual", 28 | "Type": "AWS::Amplify::Branch", 29 | "Properties": { 30 | "BranchName": { 31 | "Ref": "env" 32 | }, 33 | "AppId": { 34 | "Ref": "appId" 35 | } 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/screen/Main/Main.js: -------------------------------------------------------------------------------- 1 | import {useState} from "react"; 2 | import AppBar from "../../components/AppBar/AppBar"; 3 | import FilesAppLayout from "../../components/FilesAppLayout/FilesAppLayout"; 4 | import "@cloudscape-design/global-styles/index.css" 5 | 6 | import {defaultBreadcrumbs} from "../../components/breadcrumbs-items"; 7 | import TableListFiles from "../../components/TableListFiles/TableListFiles"; 8 | import UploadFileCard from "../../components/UploadFileCard/UploadFileCard"; 9 | import {SpaceBetween} from "@cloudscape-design/components"; 10 | 11 | export default function Main(props) { 12 | 13 | return ( 14 | <> 15 | 16 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | ); 28 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "slg-files", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@aws-amplify/predictions": "^5.0.8", 7 | "@aws-amplify/ui-react": "^4.3.2", 8 | "@cloudscape-design/components": "^3.0.159", 9 | "@cloudscape-design/global-styles": "^1.0.6", 10 | "@testing-library/jest-dom": "^5.16.5", 11 | "@testing-library/react": "^13.4.0", 12 | "@testing-library/user-event": "^13.5.0", 13 | "aws-amplify": "^5.0.8", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0", 16 | "react-router-dom": "^6.6.1", 17 | "react-scripts": "5.0.1", 18 | "web-vitals": "^2.1.4" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "eslintConfig": { 27 | "extends": [ 28 | "react-app", 29 | "react-app/jest" 30 | ] 31 | }, 32 | "browserslist": { 33 | "production": [ 34 | ">0.2%", 35 | "not dead", 36 | "not op_mini all" 37 | ], 38 | "development": [ 39 | "last 1 chrome version", 40 | "last 1 firefox version", 41 | "last 1 safari version" 42 | ] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth": { 3 | "slgfiles71a417f4": { 4 | "service": "Cognito", 5 | "providerPlugin": "awscloudformation", 6 | "dependsOn": [], 7 | "customAuth": false, 8 | "frontendAuthConfig": { 9 | "socialProviders": [], 10 | "usernameAttributes": [ 11 | "EMAIL" 12 | ], 13 | "signupAttributes": [ 14 | "EMAIL" 15 | ], 16 | "passwordProtectionSettings": { 17 | "passwordPolicyMinLength": 8, 18 | "passwordPolicyCharacters": [] 19 | }, 20 | "mfaConfiguration": "OFF", 21 | "mfaTypes": [ 22 | "SMS" 23 | ], 24 | "verificationMechanisms": [ 25 | "EMAIL" 26 | ] 27 | } 28 | } 29 | }, 30 | "storage": { 31 | "slgfiles": { 32 | "service": "S3", 33 | "providerPlugin": "awscloudformation", 34 | "dependsOn": [] 35 | } 36 | }, 37 | "hosting": { 38 | "amplifyhosting": { 39 | "service": "amplifyhosting", 40 | "providerPlugin": "awscloudformation", 41 | "type": "manual" 42 | } 43 | }, 44 | "function": {}, 45 | "api": {}, 46 | "predictions": { 47 | "identifyText77dd4f2a": { 48 | "providerPlugin": "awscloudformation", 49 | "service": "RekognitionAndTextract", 50 | "dependsOn": [], 51 | "identifyType": "identifyText" 52 | }, 53 | "interpretText99e26fde": { 54 | "providerPlugin": "awscloudformation", 55 | "service": "Comprehend", 56 | "interpretType": "interpretText" 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/components/AppBar/AppBar.js: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import TopNavigation from "@cloudscape-design/components/top-navigation"; 3 | 4 | import { Auth } from 'aws-amplify'; 5 | import {useEffect, useState} from "react"; 6 | 7 | export default () => { 8 | 9 | const [username, setUsername] = useState(""); 10 | 11 | useEffect(() => { 12 | 13 | const load = async () => { 14 | Auth.currentUserInfo().then( 15 | (result) => { 16 | setUsername(result.attributes.email); 17 | } 18 | ) 19 | }; 20 | 21 | load(); 22 | }, []); 23 | 24 | 25 | return ( 26 | 51 | ); 52 | } -------------------------------------------------------------------------------- /amplify/backend/auth/slgfiles71a417f4/cli-inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "cognitoConfig": { 4 | "identityPoolName": "slgfiles71a417f4_identitypool_71a417f4", 5 | "allowUnauthenticatedIdentities": false, 6 | "resourceNameTruncated": "slgfil71a417f4", 7 | "userPoolName": "slgfiles71a417f4_userpool_71a417f4", 8 | "autoVerifiedAttributes": [ 9 | "email" 10 | ], 11 | "mfaConfiguration": "OFF", 12 | "mfaTypes": [ 13 | "SMS Text Message" 14 | ], 15 | "smsAuthenticationMessage": "Your authentication code is {####}", 16 | "smsVerificationMessage": "Your verification code is {####}", 17 | "emailVerificationSubject": "Your verification code", 18 | "emailVerificationMessage": "Your verification code is {####}", 19 | "defaultPasswordPolicy": false, 20 | "passwordPolicyMinLength": 8, 21 | "passwordPolicyCharacters": [], 22 | "requiredAttributes": [ 23 | "email" 24 | ], 25 | "aliasAttributes": [], 26 | "userpoolClientGenerateSecret": false, 27 | "userpoolClientRefreshTokenValidity": 30, 28 | "userpoolClientWriteAttributes": [ 29 | "email" 30 | ], 31 | "userpoolClientReadAttributes": [ 32 | "email" 33 | ], 34 | "userpoolClientLambdaRole": "slgfil71a417f4_userpoolclient_lambda_role", 35 | "userpoolClientSetAttributes": false, 36 | "sharedId": "71a417f4", 37 | "resourceName": "slgfiles71a417f4", 38 | "authSelections": "identityPoolAndUserPool", 39 | "useDefault": "default", 40 | "usernameAttributes": [ 41 | "email" 42 | ], 43 | "userPoolGroupList": [], 44 | "serviceName": "Cognito", 45 | "usernameCaseSensitive": false, 46 | "useEnabledMfas": true 47 | } 48 | } -------------------------------------------------------------------------------- /amplify/cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "features": { 3 | "graphqltransformer": { 4 | "addmissingownerfields": true, 5 | "improvepluralization": false, 6 | "validatetypenamereservedwords": true, 7 | "useexperimentalpipelinedtransformer": true, 8 | "enableiterativegsiupdates": true, 9 | "secondarykeyasgsi": true, 10 | "skipoverridemutationinputtypes": true, 11 | "transformerversion": 2, 12 | "suppressschemamigrationprompt": true, 13 | "securityenhancementnotification": false, 14 | "showfieldauthnotification": false, 15 | "usesubusernamefordefaultidentityclaim": true, 16 | "usefieldnameforprimarykeyconnectionfield": false 17 | }, 18 | "frontend-ios": { 19 | "enablexcodeintegration": true 20 | }, 21 | "auth": { 22 | "enablecaseinsensitivity": true, 23 | "useinclusiveterminology": true, 24 | "breakcirculardependency": true, 25 | "forcealiasattributes": false, 26 | "useenabledmfas": true 27 | }, 28 | "codegen": { 29 | "useappsyncmodelgenplugin": true, 30 | "usedocsgeneratorplugin": true, 31 | "usetypesgeneratorplugin": true, 32 | "cleangeneratedmodelsdirectory": true, 33 | "retaincasestyle": true, 34 | "addtimestampfields": true, 35 | "handlelistnullabilitytransparently": true, 36 | "emitauthprovider": true, 37 | "generateindexrules": true, 38 | "enabledartnullsafety": true 39 | }, 40 | "appsync": { 41 | "generategraphqlpermissions": true 42 | }, 43 | "latestregionsupport": { 44 | "pinpoint": 1, 45 | "translate": 1, 46 | "transcribe": 1, 47 | "rekognition": 1, 48 | "textract": 1, 49 | "comprehend": 1 50 | }, 51 | "project": { 52 | "overrides": true 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Files 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /src/components/TableListFiles/TableListFiles.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | 3 | import "@cloudscape-design/global-styles/index.css" 4 | import {Box, Button, SpaceBetween, Table} from "@cloudscape-design/components" 5 | import Header from "@cloudscape-design/components/header"; 6 | import { Storage } from 'aws-amplify'; 7 | 8 | const columnDefinitions = [ 9 | { 10 | id: 'key', 11 | cell: item => item.key, 12 | header: 'Filename', 13 | }, 14 | { 15 | id: 'size', 16 | header: 'Size', 17 | cell: item => (item.size / 1024 / 1024).toFixed(2) + " MB", 18 | minWidth: 10, 19 | }, 20 | { 21 | id: 'lastModified', 22 | header: 'Last Modified', 23 | cell: item => item.lastModified.toString(), 24 | }, 25 | ]; 26 | 27 | function TableListFiles(props) { 28 | 29 | const [items, setItems] = useState(); 30 | const [selectedItems, setSelectedItems] = useState([]); 31 | 32 | const load = async () => { 33 | Storage.list('', {level: props.level}) 34 | .then( 35 | result => { 36 | setItems(result.results); 37 | } 38 | ) 39 | .catch((err) => console.log(err)); 40 | }; 41 | 42 | useEffect(() => { 43 | load(); 44 | }, []); 45 | 46 | function downloadFile(filename) { 47 | Storage.get(filename, { 48 | level: props.level 49 | }).then( 50 | (result) => { 51 | openInNewTab(result); 52 | } 53 | ) 54 | } 55 | 56 | function deleteFile(filename) { 57 | Storage.remove(filename, { level: props.level }).then( 58 | (ok) => { 59 | load().then( 60 | // alert("File deleted.") 61 | ); 62 | } 63 | ).catch( (error) => { 64 | console.log(error); 65 | } ); 66 | } 67 | 68 | const openInNewTab = (url) => { 69 | const newWindow = window.open(url, '_blank', 'noopener,noreferrer') 70 | if (newWindow) newWindow.opener = null 71 | } 72 | 73 | return ( 74 | 79 | setSelectedItems(detail.selectedItems) 80 | } 81 | header={ 82 |
85 | 86 | 87 | 88 | 89 | } 90 | > 91 | 92 |
93 | } 94 | selectionType="single" 95 | selectedItems={selectedItems} 96 | empty={ 97 | 98 | 99 |
100 | No files uploaded yet 101 | 102 | You don't have any files uploaded yet. 103 | 104 |
105 |
106 |
107 | } 108 | /> 109 | ); 110 | 111 | } 112 | 113 | export default TableListFiles; 114 | -------------------------------------------------------------------------------- /amplify/backend/predictions/interpretText99e26fde/interpretText99e26fde-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"8.3.1\",\"stackType\":\"predictions-Comprehend\",\"metadata\":{}}", 4 | "Parameters": { 5 | "authRoleName": { 6 | "Type": "String" 7 | }, 8 | "unauthRoleName": { 9 | "Type": "String" 10 | }, 11 | "interpretPolicyName": { 12 | "Type": "String" 13 | }, 14 | "resourceName": { 15 | "Type": "String" 16 | }, 17 | "access": { 18 | "Type": "String" 19 | }, 20 | "type": { 21 | "Type": "String" 22 | }, 23 | "interpretType": { 24 | "Type": "String" 25 | }, 26 | "env": { 27 | "Type": "String" 28 | } 29 | }, 30 | "Conditions": { 31 | "AuthGuestRoleAccess": { 32 | "Fn::Equals": [ 33 | { 34 | "Ref": "access" 35 | }, 36 | "authAndGuest" 37 | ] 38 | } 39 | }, 40 | "Outputs": { 41 | "region": { 42 | "Value": { 43 | "Fn::FindInMap": [ 44 | "RegionMapping", 45 | { 46 | "Ref": "AWS::Region" 47 | }, 48 | { 49 | "Ref": "interpretType" 50 | } 51 | ] 52 | } 53 | }, 54 | "type": { 55 | "Value": { 56 | "Ref": "type" 57 | } 58 | } 59 | }, 60 | "Resources": { 61 | "InterpretPolicy": { 62 | "Type": "AWS::IAM::Policy", 63 | "Properties": { 64 | "PolicyName": { 65 | "Ref": "interpretPolicyName" 66 | }, 67 | "Roles": { 68 | "Fn::If": [ 69 | "AuthGuestRoleAccess", 70 | [ 71 | { 72 | "Ref": "authRoleName" 73 | }, 74 | { 75 | "Ref": "unauthRoleName" 76 | } 77 | ], 78 | [ 79 | { 80 | "Ref": "authRoleName" 81 | } 82 | ] 83 | ] 84 | }, 85 | "PolicyDocument": { 86 | "Version": "2012-10-17", 87 | "Statement": [ 88 | { 89 | "Effect": "Allow", 90 | "Action": [ 91 | "comprehend:DetectSentiment", 92 | "comprehend:DetectEntities", 93 | "comprehend:DetectDominantLanguage", 94 | "comprehend:DetectSyntax", 95 | "comprehend:DetectKeyPhrases" 96 | ], 97 | "Resource": "*" 98 | } 99 | ] 100 | } 101 | } 102 | } 103 | }, 104 | "Mappings": { 105 | "RegionMapping": { 106 | "us-east-1": { 107 | "interpretText": "us-east-1" 108 | }, 109 | "us-east-2": { 110 | "interpretText": "us-east-2" 111 | }, 112 | "us-west-1": { 113 | "interpretText": "us-west-2" 114 | }, 115 | "us-west-2": { 116 | "interpretText": "us-west-2" 117 | }, 118 | "ca-central-1": { 119 | "interpretText": "ca-central-1" 120 | }, 121 | "eu-west-1": { 122 | "interpretText": "eu-west-1" 123 | }, 124 | "eu-west-2": { 125 | "interpretText": "eu-west-2" 126 | }, 127 | "eu-west-3": { 128 | "interpretText": "eu-west-1" 129 | }, 130 | "eu-central-1": { 131 | "interpretText": "eu-central-1" 132 | }, 133 | "eu-north-1": { 134 | "interpretText": "eu-central-1" 135 | }, 136 | "ap-northeast-1": { 137 | "interpretText": "ap-northeast-1" 138 | }, 139 | "ap-northeast-2": { 140 | "interpretText": "ap-northeast-2" 141 | }, 142 | "ap-southeast-1": { 143 | "interpretText": "ap-southeast-1" 144 | }, 145 | "ap-southeast-2": { 146 | "interpretText": "ap-southeast-2" 147 | }, 148 | "ap-south-1": { 149 | "interpretText": "ap-south-1" 150 | }, 151 | "me-south-1": { 152 | "interpretText": "ap-south-1" 153 | }, 154 | "sa-east-1": { 155 | "interpretText": "us-east-1" 156 | } 157 | } 158 | } 159 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Online Document Manager - Amplify Demo 2 | Online Document Manager is a **web storage solution** where authenticated users can store, access, and share files such as documents, photos, videos, etc. from anywhere with an internet connection. It allows you to keep your files organized, backed up, and easily accessible. You can also save files or documents privately or publicly for all authenticated users using a simple user interface (UI). All text documents can also be analyzed to obtain data such as number of words, tables, forms, keywords, objects, entities and analyze the sentiment in general. 3 | 4 | It was created with the [**AWS Amplify toolset**](https://docs.amplify.aws/). Amplify is a set of tools and services that enables front-end and mobile developers to build scalable full-stack applications by integrating backend cloud services (such as *Simple Storage Service -S3-, Cognito, Comprehend, Textract*, among others) with their web or mobile frontend. The user interface (UI) was created with the [**Cloudscape design**](https://cloudscape.design/), an open source design system to create beautiful web applications. It was built for and is used by Amazon Web Services (AWS) products and services. It was created in 2016 to improve the user experience across web applications owned by AWS services, and also to help teams implement those applications faster. 5 | 6 | This project was created using the following Amplify features: 7 | - **Amplify Storage**: Amplify allows you to either setup a app content storage (images, audio, video etc.) backed by Amazon S3 or a NoSQL database backed by Amazon DynamoDB. 8 | - **Amplify Authentication**: The Amplify CLI supports configuring many different Authentication and Authorization workflows, including simple and advanced configurations of the login options backed by Amazon Cognito. 9 | - **Amplify Predictions**: The Predictions category provides a solution for using AI and ML cloud services to enhance your application. Some supported use cases are: text recognition from image, entities recognition, label real world objects, interpretation of text and transcription of text. 10 | - **Amplify Hosting**: Provides a git-based workflow for continuous deployment & hosting of fullstack web apps. Cloud resources created by the Amplify CLI are also visible in the Amplify Console. 11 | 12 | ### Requirements 13 | - Have access to a AWS account with Access Key and Secret Access Key 14 | - Install **NodeJS** and **npm** 15 | - Install a **JavaScript IDE** 16 | - Install **AWS CLI** 17 | - Install **Amplify CLI** 18 | 19 | ### Steps 20 | 21 | 1. [Install Node.js®](https://nodejs.org/en/download/) and [NPM](https://www.npmjs.com/get-npm) if they are not already on your machine. 22 | 2. Verify that you are running at least Node.js version 12.x and npm version 6.x or greater by running `node -v` and `npm -v` in a terminal/console window 23 | 3. Go to your AWS Account and [create an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html). Then [define that user's permissions as narrowly as possible](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). 24 | 2. [Create the access key under that IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). 25 | 3. Copy, paste and save in a secret place your Access Key and Secret Access Key. **It is important to keep both keys in a safe place and do not redistribute this keys to anybody.** 26 | 4. [Install in your computer the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions) 27 | 5. [Install and configure Amplify CLI.](https://docs.amplify.aws/cli/start/install/) You can follow the guidelines in the previous link on how to install Amplify based on your OS. 28 | 6. Download this repository by doing `git clone https://github.com/aws-samples/online-document-manager-amplify` or simply download source code. 29 | 7. In your terminal/console window, go to your code root folder and type `npm install` to install all the dependencies. 30 | 8. Once finished, initialize AWS Amplify in the new directory by running `amplify init`. After a few configuration questions, you can use `amplify help` at any time to see the overall command structure 31 | 9. To deploy all the resources, you can use the Amplify `push` command: `amplify push` and follow guidelines. 32 | 10. Finally, we need to deploy the UI to Amplify Hosting. Execute the following command and follow instructions: `amplify publish` 33 | 34 | -------------------------------------------------------------------------------- /amplify/backend/predictions/identifyText77dd4f2a/identifyText77dd4f2a-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"8.3.1\",\"stackType\":\"predictions-RekognitionAndTextract\",\"metadata\":{}}", 4 | "Parameters": { 5 | "resourceName": { 6 | "Type": "String" 7 | }, 8 | "identifyPolicyName": { 9 | "Type": "String" 10 | }, 11 | "access": { 12 | "Type": "String" 13 | }, 14 | "authRoleName": { 15 | "Type": "String" 16 | }, 17 | "unauthRoleName": { 18 | "Type": "String" 19 | }, 20 | "adminAuthProtected": { 21 | "Type": "String" 22 | }, 23 | "adminGuestProtected": { 24 | "Type": "String" 25 | }, 26 | "identifyType": { 27 | "Type": "String" 28 | }, 29 | "identifyDoc": { 30 | "Type": "String" 31 | }, 32 | "format": { 33 | "Type": "String" 34 | }, 35 | "env": { 36 | "Type": "String" 37 | } 38 | }, 39 | "Conditions": { 40 | "CreateAdminAuthProtected": { 41 | "Fn::Not": [ 42 | { 43 | "Fn::Equals": [ 44 | { 45 | "Ref": "adminAuthProtected" 46 | }, 47 | "DISALLOW" 48 | ] 49 | } 50 | ] 51 | }, 52 | "CreateAdminGuestProtected": { 53 | "Fn::Not": [ 54 | { 55 | "Fn::Equals": [ 56 | { 57 | "Ref": "adminGuestProtected" 58 | }, 59 | "DISALLOW" 60 | ] 61 | } 62 | ] 63 | }, 64 | "ShouldNotCreateEnvResources": { 65 | "Fn::Equals": [ 66 | { 67 | "Ref": "env" 68 | }, 69 | "NONE" 70 | ] 71 | }, 72 | "AuthGuestRoleAccess": { 73 | "Fn::Equals": [ 74 | { 75 | "Ref": "access" 76 | }, 77 | "authAndGuest" 78 | ] 79 | } 80 | }, 81 | "Outputs": { 82 | "region": { 83 | "Value": { 84 | "Fn::FindInMap": [ 85 | "RegionMapping", 86 | { 87 | "Ref": "AWS::Region" 88 | }, 89 | { 90 | "Ref": "identifyType" 91 | } 92 | ] 93 | } 94 | }, 95 | "format": { 96 | "Value": { 97 | "Ref": "format" 98 | } 99 | } 100 | }, 101 | "Resources": { 102 | "IdentifyTextPolicy": { 103 | "Type": "AWS::IAM::Policy", 104 | "Properties": { 105 | "PolicyName": { 106 | "Ref": "identifyPolicyName" 107 | }, 108 | "Roles": { 109 | "Fn::If": [ 110 | "AuthGuestRoleAccess", 111 | [ 112 | { 113 | "Ref": "authRoleName" 114 | }, 115 | { 116 | "Ref": "unauthRoleName" 117 | } 118 | ], 119 | [ 120 | { 121 | "Ref": "authRoleName" 122 | } 123 | ] 124 | ] 125 | }, 126 | "PolicyDocument": { 127 | "Version": "2012-10-17", 128 | "Statement": [ 129 | { 130 | "Effect": "Allow", 131 | "Action": [ 132 | "rekognition:DetectText", 133 | "rekognition:DetectLabel", 134 | "textract:AnalyzeDocument", 135 | "textract:DetectDocumentText", 136 | "textract:GetDocumentAnalysis", 137 | "textract:StartDocumentAnalysis", 138 | "textract:StartDocumentTextDetection" 139 | ], 140 | "Resource": "*" 141 | } 142 | ] 143 | } 144 | } 145 | } 146 | }, 147 | "Mappings": { 148 | "RegionMapping": { 149 | "us-east-1": { 150 | "identifyText": "us-east-1" 151 | }, 152 | "us-east-2": { 153 | "identifyText": "us-east-2" 154 | }, 155 | "us-west-1": { 156 | "identifyText": "us-west-1" 157 | }, 158 | "us-west-2": { 159 | "identifyText": "us-west-2" 160 | }, 161 | "ca-central-1": { 162 | "identifyText": "ca-central-1" 163 | }, 164 | "eu-west-1": { 165 | "identifyText": "eu-west-1" 166 | }, 167 | "eu-west-2": { 168 | "identifyText": "eu-west-2" 169 | }, 170 | "eu-west-3": { 171 | "identifyText": "eu-west-1" 172 | }, 173 | "eu-central-1": { 174 | "identifyText": "eu-central-1" 175 | }, 176 | "eu-north-1": { 177 | "identifyText": "eu-central-1" 178 | }, 179 | "ap-northeast-1": { 180 | "identifyText": "us-east-1" 181 | }, 182 | "ap-northeast-2": { 183 | "identifyText": "ap-northeast-2" 184 | }, 185 | "ap-southeast-1": { 186 | "identifyText": "ap-southeast-1" 187 | }, 188 | "ap-southeast-2": { 189 | "identifyText": "ap-southeast-2" 190 | }, 191 | "ap-south-1": { 192 | "identifyText": "ap-south-1" 193 | }, 194 | "me-south-1": { 195 | "identifyText": "ap-south-1" 196 | }, 197 | "sa-east-1": { 198 | "identifyText": "us-east-1" 199 | } 200 | } 201 | } 202 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Amplify ### 2 | # AWS Amplify 3 | amplify/\#current-cloud-backend 4 | amplify/team-provider-info.json 5 | amplify/.config/local-* 6 | amplify/mock-data 7 | amplify/backend/amplify-meta.json 8 | amplify/backend/awscloudformation 9 | build/ 10 | dist/ 11 | node_modules/ 12 | aws-exports.js 13 | awsconfiguration.json 14 | amplifyconfiguration.json 15 | amplify-build-config.json 16 | amplify-gradle-config.json 17 | amplifyxc.config 18 | 19 | ### macOS ### 20 | # General 21 | .DS_Store 22 | .AppleDouble 23 | .LSOverride 24 | 25 | # Icon must end with two \r 26 | Icon 27 | 28 | 29 | # Thumbnails 30 | ._* 31 | 32 | # Files that might appear in the root of a volume 33 | .DocumentRevisions-V100 34 | .fseventsd 35 | .Spotlight-V100 36 | .TemporaryItems 37 | .Trashes 38 | .VolumeIcon.icns 39 | .com.apple.timemachine.donotpresent 40 | 41 | # Directories potentially created on remote AFP share 42 | .AppleDB 43 | .AppleDesktop 44 | Network Trash Folder 45 | Temporary Items 46 | .apdisk 47 | 48 | ### macOS Patch ### 49 | # iCloud generated files 50 | *.icloud 51 | 52 | ### Node ### 53 | # Logs 54 | logs 55 | *.log 56 | npm-debug.log* 57 | yarn-debug.log* 58 | yarn-error.log* 59 | lerna-debug.log* 60 | .pnpm-debug.log* 61 | 62 | # Diagnostic reports (https://nodejs.org/api/report.html) 63 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 64 | 65 | # Runtime data 66 | pids 67 | *.pid 68 | *.seed 69 | *.pid.lock 70 | 71 | # Directory for instrumented libs generated by jscoverage/JSCover 72 | lib-cov 73 | 74 | # Coverage directory used by tools like istanbul 75 | coverage 76 | *.lcov 77 | 78 | # nyc test coverage 79 | .nyc_output 80 | 81 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 82 | .grunt 83 | 84 | # Bower dependency directory (https://bower.io/) 85 | bower_components 86 | 87 | # node-waf configuration 88 | .lock-wscript 89 | 90 | # Compiled binary addons (https://nodejs.org/api/addons.html) 91 | build/Release 92 | 93 | # Dependency directories 94 | jspm_packages/ 95 | 96 | # Snowpack dependency directory (https://snowpack.dev/) 97 | web_modules/ 98 | 99 | # TypeScript cache 100 | *.tsbuildinfo 101 | 102 | # Optional npm cache directory 103 | .npm 104 | 105 | # Optional eslint cache 106 | .eslintcache 107 | 108 | # Optional stylelint cache 109 | .stylelintcache 110 | 111 | # Microbundle cache 112 | .rpt2_cache/ 113 | .rts2_cache_cjs/ 114 | .rts2_cache_es/ 115 | .rts2_cache_umd/ 116 | 117 | # Optional REPL history 118 | .node_repl_history 119 | 120 | # Output of 'npm pack' 121 | *.tgz 122 | 123 | # Yarn Integrity file 124 | .yarn-integrity 125 | 126 | # dotenv environment variable files 127 | .env 128 | .env.development.local 129 | .env.test.local 130 | .env.production.local 131 | .env.local 132 | 133 | # parcel-bundler cache (https://parceljs.org/) 134 | .cache 135 | .parcel-cache 136 | 137 | # Next.js build output 138 | .next 139 | out 140 | 141 | # Nuxt.js build / generate output 142 | .nuxt 143 | dist 144 | 145 | # Gatsby files 146 | .cache/ 147 | # Comment in the public line in if your project uses Gatsby and not Next.js 148 | # https://nextjs.org/blog/next-9-1#public-directory-support 149 | # public 150 | 151 | # vuepress build output 152 | .vuepress/dist 153 | 154 | # vuepress v2.x temp and cache directory 155 | .temp 156 | 157 | # Docusaurus cache and generated files 158 | .docusaurus 159 | 160 | # Serverless directories 161 | .serverless/ 162 | 163 | # FuseBox cache 164 | .fusebox/ 165 | 166 | # DynamoDB Local files 167 | .dynamodb/ 168 | 169 | # TernJS port file 170 | .tern-port 171 | 172 | # Stores VSCode versions used for testing VSCode extensions 173 | .vscode-test 174 | 175 | # yarn v2 176 | .yarn/cache 177 | .yarn/unplugged 178 | .yarn/build-state.yml 179 | .yarn/install-state.gz 180 | .pnp.* 181 | 182 | ### Node Patch ### 183 | # Serverless Webpack directories 184 | .webpack/ 185 | 186 | # Optional stylelint cache 187 | 188 | # SvelteKit build / generate output 189 | .svelte-kit 190 | 191 | ### react ### 192 | .DS_* 193 | **/*.backup.* 194 | **/*.back.* 195 | 196 | node_modules 197 | 198 | *.sublime* 199 | 200 | psd 201 | thumb 202 | sketch 203 | 204 | ### WebStorm+all ### 205 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 206 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 207 | 208 | # User-specific stuff 209 | .idea/**/workspace.xml 210 | .idea/**/tasks.xml 211 | .idea/**/usage.statistics.xml 212 | .idea/**/dictionaries 213 | .idea/**/shelf 214 | 215 | # AWS User-specific 216 | .idea/**/aws.xml 217 | 218 | # Generated files 219 | .idea/**/contentModel.xml 220 | 221 | # Sensitive or high-churn files 222 | .idea/**/dataSources/ 223 | .idea/**/dataSources.ids 224 | .idea/**/dataSources.local.xml 225 | .idea/**/sqlDataSources.xml 226 | .idea/**/dynamic.xml 227 | .idea/**/uiDesigner.xml 228 | .idea/**/dbnavigator.xml 229 | 230 | # Gradle 231 | .idea/**/gradle.xml 232 | .idea/**/libraries 233 | 234 | # Gradle and Maven with auto-import 235 | # When using Gradle or Maven with auto-import, you should exclude module files, 236 | # since they will be recreated, and may cause churn. Uncomment if using 237 | # auto-import. 238 | # .idea/artifacts 239 | # .idea/compiler.xml 240 | # .idea/jarRepositories.xml 241 | # .idea/modules.xml 242 | # .idea/*.iml 243 | # .idea/modules 244 | # *.iml 245 | # *.ipr 246 | 247 | # CMake 248 | cmake-build-*/ 249 | 250 | # Mongo Explorer plugin 251 | .idea/**/mongoSettings.xml 252 | 253 | # File-based project format 254 | *.iws 255 | 256 | # IntelliJ 257 | out/ 258 | 259 | # mpeltonen/sbt-idea plugin 260 | .idea_modules/ 261 | 262 | # JIRA plugin 263 | atlassian-ide-plugin.xml 264 | 265 | # Cursive Clojure plugin 266 | .idea/replstate.xml 267 | 268 | # SonarLint plugin 269 | .idea/sonarlint/ 270 | 271 | # Crashlytics plugin (for Android Studio and IntelliJ) 272 | com_crashlytics_export_strings.xml 273 | crashlytics.properties 274 | crashlytics-build.properties 275 | fabric.properties 276 | 277 | # Editor-based Rest Client 278 | .idea/httpRequests 279 | 280 | # Android studio 3.1+ serialized cache file 281 | .idea/caches/build_file_checksums.ser 282 | 283 | ### WebStorm+all Patch ### 284 | # Ignore everything but code style settings and run configurations 285 | # that are supposed to be shared within teams. 286 | 287 | .idea/* 288 | 289 | !.idea/codeStyles 290 | !.idea/runConfigurations 291 | 292 | ### Windows ### 293 | # Windows thumbnail cache files 294 | Thumbs.db 295 | Thumbs.db:encryptable 296 | ehthumbs.db 297 | ehthumbs_vista.db 298 | 299 | # Dump file 300 | *.stackdump 301 | 302 | # Folder config file 303 | [Dd]esktop.ini 304 | 305 | # Recycle Bin used on file shares 306 | $RECYCLE.BIN/ 307 | 308 | # Windows Installer files 309 | *.cab 310 | *.msi 311 | *.msix 312 | *.msm 313 | *.msp 314 | 315 | # Windows shortcuts 316 | *.lnk 317 | -------------------------------------------------------------------------------- /src/components/UploadFileCard/UploadFileCard.js: -------------------------------------------------------------------------------- 1 | import {useEffect, useState} from "react"; 2 | 3 | import "@cloudscape-design/global-styles/index.css" 4 | import { 5 | Button, 6 | Container, 7 | ExpandableSection, Flashbar, 8 | Form, 9 | FormField, Grid, Header, Input, PieChart, 10 | ProgressBar, 11 | SpaceBetween, Table, TokenGroup 12 | } from "@cloudscape-design/components" 13 | 14 | import {Amplify, Storage} from 'aws-amplify'; 15 | import {Predictions, AmazonAIPredictionsProvider} from '@aws-amplify/predictions'; 16 | 17 | Amplify.addPluggable(new AmazonAIPredictionsProvider()); 18 | 19 | function UploadFileCard(props) { 20 | 21 | const [filename, setFilename] = useState(); 22 | const [progress, setProgress] = useState(); 23 | const [uploaded, setUploaded] = useState(false); 24 | 25 | const [identify, setIdentify] = useState(); 26 | const [interpret, setInterpret] = useState(); 27 | const [identifyErr, setIdentifyErr] = useState(null); 28 | const [keyValueTokenGroup, setKeyValueTokenGroup] = useState(); 29 | const [firstLinesTokenGroup, setFirstLinesTokenGroup] = useState(); 30 | 31 | 32 | async function onChange(e) { 33 | setProgress(0); 34 | const file = e.target.files[0]; 35 | setFilename(file.name); 36 | 37 | try { 38 | var response = await Storage.put(file.name, file, { 39 | progressCallback(progress) { 40 | setProgress(progress.loaded * 100 / progress.total); 41 | }, 42 | level: props.level, 43 | useAccelerateEndpoint: true 44 | }); 45 | setUploaded(true); 46 | } catch (error) { 47 | console.log("Error uploading file: ", error); 48 | } 49 | 50 | var responseIdentify = await onIdentify(file); 51 | var responseInterpret = await onInterpret(responseIdentify.text.fullText); 52 | 53 | } 54 | 55 | async function onIdentify(file) { 56 | 57 | try { 58 | var respPrediction = await Predictions.identify({ 59 | text: { 60 | source: { 61 | file 62 | } 63 | } 64 | }); 65 | 66 | setIdentify(respPrediction); 67 | console.log(respPrediction); 68 | 69 | var keyValuesGroupArray = []; 70 | var firstLinesGroupArray = []; 71 | 72 | respPrediction.text.keyValues.forEach( 73 | (each) => { 74 | keyValuesGroupArray.push({ 75 | label: each.key, 76 | // dismissLabel: "Remove" 77 | }) 78 | } 79 | ); 80 | 81 | for (var i = 0; i < Math.min(5, respPrediction.text.lines.length); i++) { 82 | firstLinesGroupArray.push({ 83 | label: "Line " + i + ": " + respPrediction.text.lines[i], 84 | }) 85 | } 86 | 87 | setKeyValueTokenGroup(keyValuesGroupArray); 88 | setFirstLinesTokenGroup(firstLinesGroupArray); 89 | setIdentifyErr(null); 90 | 91 | return respPrediction; 92 | 93 | 94 | } catch (error) { 95 | console.log("Error uploading file: ", error); 96 | 97 | setIdentify(); 98 | setKeyValueTokenGroup(); 99 | setFirstLinesTokenGroup(); 100 | setIdentifyErr({ 101 | header: "Text identification data error - No valid data", 102 | type: "error", 103 | content: "This function only works for PDF files.", 104 | id: "message_error" 105 | }); 106 | 107 | return null; 108 | 109 | } 110 | 111 | } 112 | 113 | async function onInterpret(fullText) { 114 | 115 | try { 116 | var respPredictions = await Predictions.interpret({ 117 | text: { 118 | source: { 119 | text: fullText, 120 | }, 121 | type: "ALL" 122 | } 123 | }); 124 | 125 | setInterpret(respPredictions); 126 | } catch (e) { 127 | console.log(e); 128 | } 129 | 130 | } 131 | 132 | function retrieveItems(){ 133 | var textEntitiesArray = []; 134 | var aMap = {}; 135 | 136 | interpret.textInterpretation.textEntities.forEach( 137 | (each) => { 138 | aMap[each.type] ??= []; 139 | aMap[each.type].push(each.text); 140 | } 141 | ); 142 | 143 | for (let key in aMap) { 144 | textEntitiesArray.push({ 145 | 'type' : key, 146 | 'text' : aMap[key].join(', '), 147 | }) 148 | } 149 | 150 | return textEntitiesArray; 151 | } 152 | 153 | return ( 154 | 155 | 156 | 157 | 161 | 162 |
163 | 165 | 166 | 171 | 172 | {/**/} 177 | 178 | {/**/} 183 | 184 | {/**/} 189 | 190 | 191 | 192 |
193 | 194 | { 195 | identify == null || identify === undefined ? 196 | <> : 197 | 198 |
199 | 202 | 203 | 204 | 208 | 209 | 210 | 214 | 215 | 216 | 220 | 221 | 222 | 226 | 227 | 228 | 232 | 233 | 234 |
235 | Key Values found 236 |
237 | 240 | 241 |
242 | First lines found 243 |
244 | 247 | 248 | { 249 | interpret == null || interpret === undefined ? 250 | <> : 251 | <> 252 |
253 | Sentiment 254 |
255 | [ 276 | {key: "Value", value: datum.value}, 277 | { 278 | key: "Percentage", 279 | value: datum.value.toFixed(2) + " %" 280 | }, 281 | ]} 282 | /> 283 | 284 |
item.type || "-", 290 | }, 291 | { 292 | id: "text", 293 | header: "Labels found", 294 | cell: item => item.text || "-", 295 | }, 296 | ]} 297 | items={retrieveItems()} 298 | loadingText="Loading resources" 299 | sortingDisabled 300 | variant="embedded" 301 | /> 302 | 303 | } 304 | 305 | 306 | 307 | 308 | } 309 | 310 | 311 | 312 | ); 313 | 314 | } 315 | 316 | export default UploadFileCard; 317 | --------------------------------------------------------------------------------