4 Commits

Author SHA1 Message Date
b4e5dd74d9 chore: licence checker sync
All checks were successful
Test / Build-production-and-ng-test (push) Successful in 6m27s
Test / Build-and-test-development (push) Successful in 12m0s
Test / Build-and-test-development-latest-adapter (push) Successful in 11m55s
2023-10-12 14:55:22 +02:00
64746b0aae Merge pull request 'sheetjs' (#53) from sheetjs into development
Some checks failed
Test / Build-production-and-ng-test (push) Failing after 3m15s
Test / Build-and-test-development-latest-adapter (push) Has been cancelled
Test / Build-and-test-development (push) Has been cancelled
Reviewed-on: #53
2023-10-12 12:52:31 +00:00
16ae77c804 style: lint
Some checks failed
Build / Build-and-ng-test (pull_request) Failing after 1m23s
2023-10-12 14:50:55 +02:00
481c14f066 fix: reverting SheetJS upgrade, it was breaking the excel upload 2023-10-12 14:50:34 +02:00
299 changed files with 23553 additions and 27183 deletions

View File

@ -1,5 +1,5 @@
name: Build name: Build
run-name: Running Lint Check and Licence checker on Pull Request run-name: Running Lint Check
on: [pull_request] on: [pull_request]
jobs: jobs:
@ -8,16 +8,9 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: 20.14.0 node-version: 18
- name: Install Google Chrome
run: |
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list
apt-get update
apt-get install -y google-chrome-stable xvfb
- name: Write .npmrc file - name: Write .npmrc file
run: echo "$NPMRC" > client/.npmrc run: echo "$NPMRC" > client/.npmrc
@ -25,117 +18,8 @@ jobs:
env: env:
NPMRC: ${{ secrets.NPMRC}} NPMRC: ${{ secrets.NPMRC}}
- name: Lint check - run: npm run lint:check
run: npm run lint:check - run: |
- name: Install dependencies
run: |
cd client cd client
# Decrypt and Install sheet
echo ${{ secrets.SHEET_PWD }} | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
npm ci npm ci
- name: Licence checker
run: |
cd client
npm run license-checker npm run license-checker
- name: Angular Tests
run: |
cd client
npm run test:headless
- name: Production Build
run: |
cd client
npm run build
Build-and-test-development:
runs-on: ubuntu-latest
needs: Build-production-and-ng-test
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: 20.14.0
- name: Write .npmrc file
run: |
touch client/.npmrc
echo '${{ secrets.NPMRC}}' > client/.npmrc
- run: apt-get update
- run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- run: apt install -y ./google-chrome*.deb;
- run: export CHROME_BIN=/usr/bin/google-chrome
- run: apt-get update -y
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
- run: apt -y install jq
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: |
cd client
# Decrypt and Install sheet
echo ${{ secrets.SHEET_PWD }} | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
npm ci
# Install pm2 and prepare SASJS server
- run: npm i -g pm2
- run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip
- run: unzip linux.zip
- run: touch .env
- run: echo RUN_TIMES=js >> .env
- run: echo NODE_PATH=node >> .env
- run: echo CORS=enable >> .env
- run: echo WHITELIST=http://localhost:4200 >> .env
- run: cat .env
- run: pm2 start api-linux --wait-ready
- name: Deploy mocked services
run: |
cd ./sas/mocks/sasjs
npm install -g @sasjs/cli
npm install -g replace-in-files-cli
sasjs cbd -t server-ci
# sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json
- name: Install ZIP
run: |
apt-get update
apt-get install zip
- name: Prepare and run frontend and cypress
run: |
cd ./client
mv ./cypress.env.example.json ./cypress.env.json
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
cat ./cypress.env.json
npm run postinstall
# Prepare index.html to SASJS local
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
cat ./cypress.config.ts
# Start frontend and run cypress
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel-multi-load.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/csv.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
- name: Zip Cypress videos
if: always()
run: |
zip -r cypress-videos ./client/cypress/videos
- name: Add cypress videos artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: cypress-videos.zip
path: cypress-videos.zip

View File

@ -0,0 +1,226 @@
name: Test
run-name: Building and testing development branch
on:
push:
branches:
- development
jobs:
Build-production-and-ng-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Write .npmrc file
run: |
touch client/.npmrc
echo '${{ secrets.NPMRC}}' > client/.npmrc
- name: Install Chrome for Angular tests
run: |
apt-get update
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt install -y ./google-chrome*.deb;
export CHROME_BIN=/usr/bin/google-chrome
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: npm ci
- name: Check audit
# Audit should fail and stop the CI if critical vulnerability found
run: |
npm audit --audit-level=critical --omit=dev
cd ./sas
npm audit --audit-level=critical --omit=dev
cd ../client
npm audit --audit-level=critical --omit=dev
- name: Angular Tests
run: |
cd client
npm test -- --no-watch --no-progress --browsers=ChromeHeadlessCI
- name: Angular Production Build
run: |
cd client
npm run postinstall
npm run build
Build-and-test-development:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Write .npmrc file
run: |
touch client/.npmrc
echo '${{ secrets.NPMRC}}' > client/.npmrc
- run: apt-get update
- run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- run: apt install -y ./google-chrome*.deb;
- run: export CHROME_BIN=/usr/bin/google-chrome
- run: apt-get update -y
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
- run: apt -y install jq
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: npm ci
# Install pm2 and prepare SASJS server
- run: npm i -g pm2
- run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip
- run: unzip linux.zip
- run: touch .env
- run: echo RUN_TIMES=js >> .env
- run: echo NODE_PATH=node >> .env
- run: echo CORS=enable >> .env
- run: echo WHITELIST=http://localhost:4200 >> .env
- run: cat .env
- run: pm2 start api-linux --wait-ready
- name: Deploy mocked services
run: |
cd ./sas/mocks/sasjs
npm install -g @sasjs/cli
npm install -g replace-in-files-cli
sasjs cbd -t server-ci
# sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json
- name: Install ZIP
run: |
apt-get update
apt-get install zip
- name: Prepare and run frontend and cypress
run: |
cd ./client
mv ./cypress.env.example.json ./cypress.env.json
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
cat ./cypress.env.json
npm run postinstall
# Prepare index.html to SASJS local
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
cat ./cypress.config.ts
# Start frontend and run cypress
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
- name: Zip Cypress videos
if: always()
run: |
zip -r cypress-videos ./client/cypress/videos
- name: Cypress videos artifacts
uses: actions/upload-artifact@v3
with:
name: cypress-videos.zip
path: cypress-videos.zip
Build-and-test-development-latest-adapter:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Write .npmrc file
run: echo "$NPMRC" > client/.npmrc
shell: bash
env:
NPMRC: ${{ secrets.NPMRC}}
- run: apt-get update
- run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- run: apt install -y ./google-chrome*.deb;
- run: export CHROME_BIN=/usr/bin/google-chrome
- run: apt-get update -y
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
- run: apt -y install jq
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: npm ci
# Install pm2 and prepare SASJS server
- run: npm i -g pm2
- run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip
- run: unzip linux.zip
- run: touch .env
- run: echo RUN_TIMES=js >> .env
- run: echo NODE_PATH=node >> .env
- run: echo CORS=enable >> .env
- run: echo WHITELIST=http://localhost:4200 >> .env
- run: cat .env
- run: pm2 start api-linux --wait-ready
- name: Deploy mocked services
run: |
cd ./sas/mocks/sasjs
npm install -g @sasjs/cli
npm install -g replace-in-files-cli
sasjs cbd -t server-ci
- name: Install ZIP
run: |
apt-get update
apt-get install zip
- name: Prepare and run frontend and cypress
run: |
cd ./client
mv ./cypress.env.example.json ./cypress.env.json
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
cat ./cypress.env.json
npm run postinstall
npm install @sasjs/adapter@latest
# Prepare index.html to SASJS local
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
cat ./cypress.config.ts
# Start frontend and run cypress
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
- name: Zip Cypress videos
if: always()
run: |
zip -r cypress-videos ./client/cypress/videos
- name: Cypress videos artifacts
uses: actions/upload-artifact@v3
with:
name: cypress-videos-latest-adapter.zip
path: cypress-videos.zip

View File

@ -1,164 +1,18 @@
name: Release name: Release
run-name: Testing and Releasing DC run-name: Releasing DC
on: on:
push: push:
branches: branches:
- main - main
jobs: jobs:
Build-production-and-ng-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: 20.14.0
- name: Write .npmrc file
run: |
touch client/.npmrc
echo '${{ secrets.NPMRC}}' > client/.npmrc
- name: Install Chrome for Angular tests
run: |
apt-get update
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt install -y ./google-chrome*.deb;
export CHROME_BIN=/usr/bin/google-chrome
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: |
cd client
# Decrypt and Install sheet
echo ${{ secrets.SHEET_PWD }} | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
npm ci
- name: Check audit
# Audit should fail and stop the CI if critical vulnerability found
run: |
npm audit --audit-level=critical --omit=dev
cd ./sas
npm audit --audit-level=critical --omit=dev
cd ../client
npm audit --audit-level=critical --omit=dev
- name: Angular Tests
run: |
cd client
npm run test:headless
- name: Angular Production Build
run: |
cd client
npm run postinstall
npm run build
Build-and-test-development:
runs-on: ubuntu-latest
needs: Build-production-and-ng-test
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v4
with:
node-version: 20.14.0
- name: Write .npmrc file
run: |
touch client/.npmrc
echo '${{ secrets.NPMRC}}' > client/.npmrc
- run: apt-get update
- run: wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
- run: apt install -y ./google-chrome*.deb;
- run: export CHROME_BIN=/usr/bin/google-chrome
- run: apt-get update -y
- run: apt-get -y install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb
- run: apt -y install jq
- name: Write cypress credentials
run: echo "$CYPRESS_CREDS" > ./client/cypress.env.json
shell: bash
env:
CYPRESS_CREDS: ${{ secrets.CYPRESS_CREDS }}
- name: Install dependencies
run: |
cd client
# Decrypt and Install sheet
echo ${{ secrets.SHEET_PWD }} | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
npm ci
# Install pm2 and prepare SASJS server
- run: npm i -g pm2
- run: curl -L https://github.com/sasjs/server/releases/latest/download/linux.zip > linux.zip
- run: unzip linux.zip
- run: touch .env
- run: echo RUN_TIMES=js >> .env
- run: echo NODE_PATH=node >> .env
- run: echo CORS=enable >> .env
- run: echo WHITELIST=http://localhost:4200 >> .env
- run: cat .env
- run: pm2 start api-linux --wait-ready
- name: Deploy mocked services
run: |
cd ./sas/mocks/sasjs
npm install -g @sasjs/cli
npm install -g replace-in-files-cli
sasjs cbd -t server-ci
# sasjs request services/admin/makedata -t server-ci -d ./deploy/makeData4GL.json -c ./deploy/requestConfig.json -o ./output.json
- name: Install ZIP
run: |
apt-get update
apt-get install zip
- name: Prepare and run frontend and cypress
run: |
cd ./client
mv ./cypress.env.example.json ./cypress.env.json
replace-in-files --regex='"username".*' --replacement='"username":"'${{ secrets.CYPRESS_USERNAME_SASJS }}'",' ./cypress.env.json
replace-in-files --regex='"password".*' --replacement='"password":"'${{ secrets.CYPRESS_PWD_SASJS }}'" ' ./cypress.env.json
cat ./cypress.env.json
npm run postinstall
# Prepare index.html to SASJS local
replace-in-files --regex='serverUrl=".*?"' --replacement='serverUrl="http://localhost:5000"' ./src/index.html
replace-in-files --regex='appLoc=".*?"' --replacement='appLoc="/Public/app/devtest"' ./src/index.html
replace-in-files --regex='serverType=".*?"' --replacement='serverType="SASJS"' ./src/index.html
replace-in-files --regex='"hosturl".*' --replacement='hosturl:"http://localhost:4200",' ./cypress.config.ts
cat ./cypress.config.ts
# Start frontend and run cypress
npm start & npx wait-on http://localhost:4200 && npx cypress run --browser chrome --spec "cypress/e2e/liveness.cy.ts,cypress/e2e/editor.cy.ts,cypress/e2e/excel-multi-load.cy.ts,cypress/e2e/excel.cy.ts,cypress/e2e/csv.cy.ts,cypress/e2e/filtering.cy.ts,cypress/e2e/licensing.cy.ts"
- name: Zip Cypress videos
if: always()
run: |
zip -r cypress-videos ./client/cypress/videos
- name: Add cypress videos artifacts
if: always()
uses: actions/upload-artifact@v3
with:
name: cypress-videos.zip
path: cypress-videos.zip
release: release:
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [Build-production-and-ng-test, Build-and-test-development]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-node@v4 - uses: actions/setup-node@v3
with: with:
node-version: 20.14.0 node-version: 18
- name: Write .npmrc file - name: Write .npmrc file
run: | run: |
@ -176,19 +30,6 @@ jobs:
npm i -g @sasjs/cli npm i -g @sasjs/cli
# jq is used to parse the release JSON # jq is used to parse the release JSON
apt-get install jq -y apt-get install jq -y
# doxygen is used for the SASJS docs
apt-get update
apt-get install doxygen -y
- name: Frontend Preliminary Build
description: We want to prevent creating empty release if frontend fails
run: |
cd client
# Decrypt and Install sheet
echo ${{ secrets.SHEET_PWD }} | gpg --batch --yes --passphrase-fd 0 ./libraries/sheet-crypto.tgz.gpg
npm ci
npm i webpack
npm run build
- name: Create Empty Release (assets are posted later) - name: Create Empty Release (assets are posted later)
run: | run: |
@ -202,6 +43,7 @@ jobs:
description: Must be created AFTER the release as the version (git tag) is used in the interface description: Must be created AFTER the release as the version (git tag) is used in the interface
run: | run: |
cd client cd client
npm ci
npm run build npm run build
- name: Build SAS9 EBI Release - name: Build SAS9 EBI Release
@ -245,7 +87,6 @@ jobs:
rm sasjsbuild/services/clickme.html rm sasjsbuild/services/clickme.html
sasjs b -t viya sasjs b -t viya
cp sasjsbuild/viya.sas ./viya.sas cp sasjsbuild/viya.sas ./viya.sas
cp sasjsbuild/viya.json ./viya.json
- name: Zip Frontend (including viya.json for full viya deploy) - name: Zip Frontend (including viya.json for full viya deploy)
run: | run: |
@ -261,12 +102,6 @@ jobs:
npm run compodoc:build npm run compodoc:build
surfer put --token ${{ secrets.TSDOC_TOKEN }} --server webdoc.datacontroller.io documentation/* / surfer put --token ${{ secrets.TSDOC_TOKEN }} --server webdoc.datacontroller.io documentation/* /
- name: Release code.datacontroller.io
run: |
cd sas
sasjs doc
surfer put --token ${{ secrets.CODE_DATACONTROLLER_IO }} --server code.datacontroller.io sasjsbuild/sasdocs/* /
- name: Upload assets to release - name: Upload assets to release
run: | run: |
RELEASE_ID=`curl -k 'https://git.datacontroller.io/api/v1/repos/dc/dc/releases/latest?access_token=${{ secrets.RELEASE_TOKEN }}' | jq -r '.id'` RELEASE_ID=`curl -k 'https://git.datacontroller.io/api/v1/repos/dc/dc/releases/latest?access_token=${{ secrets.RELEASE_TOKEN }}' | jq -r '.id'`
@ -281,4 +116,3 @@ jobs:
curl -k $URL -F attachment=@sas/sasjs_server.json.zip curl -k $URL -F attachment=@sas/sasjs_server.json.zip
curl -k $URL -F attachment=@sas/sas9.sas curl -k $URL -F attachment=@sas/sas9.sas
curl -k $URL -F attachment=@sas/viya.sas curl -k $URL -F attachment=@sas/viya.sas
curl -k $URL -F attachment=@sas/viya.json

3
.gitignore vendored
View File

@ -11,9 +11,6 @@ client/cypress/screenshots
client/cypress/results client/cypress/results
client/cypress/videos client/cypress/videos
client/documentation client/documentation
client/**/sheet-crypto.tgz
client/.nx
client/libraries/sheet-crypto.tgz
cypress.env.json cypress.env.json
sasjsbuild sasjsbuild
sasjsresults sasjsresults

33
.vscode/settings.json vendored
View File

@ -1,19 +1,18 @@
{ {
"cSpell.words": [ "cSpell.words": [
"Licence", "SYSERRORTEXT",
"SYSERRORTEXT", "SYSWARNINGTEXT"
"SYSWARNINGTEXT", ],
"xlmaprules", "editor.rulers": [
"xlmaps" 80
], ],
"editor.rulers": [80], "files.trimTrailingWhitespace": true,
"files.trimTrailingWhitespace": true, "[markdown]": {
"[markdown]": { "files.trimTrailingWhitespace": false
"files.trimTrailingWhitespace": false },
}, "workbench.colorCustomizations": {
"workbench.colorCustomizations": { "titleBar.activeForeground": "#ebe8e8",
"titleBar.activeForeground": "#ebe8e8", "titleBar.activeBackground": "#95ff0053",
"titleBar.activeBackground": "#95ff0053" },
}, "terminal.integrated.wordSeparators": " ()[]{}',\"`─‘’"
"terminal.integrated.wordSeparators": " ()[]{}',\"`─‘’"
} }

View File

@ -1,442 +1,3 @@
## [6.14.10](https://git.datacontroller.io/dc/dc/compare/v6.14.9...v6.14.10) (2025-06-02)
### Bug Fixes
* bump core ([0e8503e](https://git.datacontroller.io/dc/dc/commit/0e8503ed2bb22a0fc3924ac929e7f19626772e0a))
* default to home directory for SAS Drive in Viya ([9682b54](https://git.datacontroller.io/dc/dc/commit/9682b548e6106d99d97dcc023a35d93addfd5170))
## [6.14.9](https://git.datacontroller.io/dc/dc/compare/v6.14.8...v6.14.9) (2025-06-02)
### Bug Fixes
* default DC path for viya ([f3125ff](https://git.datacontroller.io/dc/dc/commit/f3125ff4641e47e33cb203228f5b1014ea3343bc))
## [6.14.8](https://git.datacontroller.io/dc/dc/compare/v6.14.7...v6.14.8) (2025-05-28)
### Bug Fixes
* CSP issues, clarity local library build, fixed some style issues ([841201a](https://git.datacontroller.io/dc/dc/commit/841201adab582149b1cca3a42e75f7cac75167f9))
* deploy page, makedata error handling, added local build of clarity, to address clr-stack-view CSP issues (inline styles) ([7b5e7ae](https://git.datacontroller.io/dc/dc/commit/7b5e7ae18414152f9b9d8f2d94fc94de43152003))
* improved deploy flow for Viya ([9604661](https://git.datacontroller.io/dc/dc/commit/9604661f3b76111387bc9474cc26348d73ab112e))
* requests modal causing VIYA CSP errors ([1dc6934](https://git.datacontroller.io/dc/dc/commit/1dc69341cadb837e1f11624d5cf35788bbb98d96))
* sas viya service init timing issue ([9de04e9](https://git.datacontroller.io/dc/dc/commit/9de04e9a0ce016e1a9fb8b19c656077079ddcf2f))
* scss of components transferred to the global styles.scss so we do not cause CSP (inline styles) issues when streaming to Viya ([6c171a6](https://git.datacontroller.io/dc/dc/commit/6c171a6394aba8104fe0f50aa8a4e6b9fa8023a2))
* viya deploy page improved flow ([4bd2154](https://git.datacontroller.io/dc/dc/commit/4bd215491f8cdc68f78bade68e7cb98e07edc81e))
## [6.14.7](https://git.datacontroller.io/dc/dc/compare/v6.14.6...v6.14.7) (2025-05-08)
### Bug Fixes
* updated hot, clarity and improved accessibility score. ([2844c70](https://git.datacontroller.io/dc/dc/commit/2844c70f9507036216b8b621900c2bb9010c1d34))
## [6.14.6](https://git.datacontroller.io/dc/dc/compare/v6.14.5...v6.14.6) (2025-04-03)
### Bug Fixes
* history table modal links styling ([c63fcdd](https://git.datacontroller.io/dc/dc/commit/c63fcdd465950ada439d7d69622a3886e8f3a783))
## [6.14.5](https://git.datacontroller.io/dc/dc/compare/v6.14.4...v6.14.5) (2025-03-24)
### Bug Fixes
* improving accessibility lighthouse score ([7f3577c](https://git.datacontroller.io/dc/dc/commit/7f3577c3ef9f44e55a58bc64fbf89a3a64006dd4))
* prevent errors when using sqlrc in a DI job in a HOOK ([d1f0879](https://git.datacontroller.io/dc/dc/commit/d1f0879f0acf7e816c80f7635fd02f4f284214ed))
* user profile style fix, new select library and table icons ([69f8830](https://git.datacontroller.io/dc/dc/commit/69f883034fabbed31aa5d832e20561c4ae3042db))
## [6.14.4](https://git.datacontroller.io/dc/dc/compare/v6.14.3...v6.14.4) (2025-03-18)
### Bug Fixes
* removing cli dependency warnings2 ([43c0f73](https://git.datacontroller.io/dc/dc/commit/43c0f73c2189ff762986a964caae6b0b108164fc))
## [6.14.3](https://git.datacontroller.io/dc/dc/compare/v6.14.2...v6.14.3) (2025-03-15)
### Bug Fixes
* NLDAT & NLDATM formats are now being staged ([3f5cb1e](https://git.datacontroller.io/dc/dc/commit/3f5cb1e2defe390220e904e4bf04a165cb31fec4))
## [6.14.2](https://git.datacontroller.io/dc/dc/compare/v6.14.1...v6.14.2) (2025-03-10)
### Bug Fixes
* improving instructions for setup ([83b3d77](https://git.datacontroller.io/dc/dc/commit/83b3d775b6e33653b087ca9f4eb3ad5b0dbbd479))
## [6.14.1](https://git.datacontroller.io/dc/dc/compare/v6.14.0...v6.14.1) (2025-03-05)
### Bug Fixes
* handle national language datetime formats ([149e318](https://git.datacontroller.io/dc/dc/commit/149e318a8787be0109f25aeec3a1270ea75a97b2))
* updating logic to use NLDAT formats ([95289aa](https://git.datacontroller.io/dc/dc/commit/95289aa9524d3cb2b1c248cfb84f6b0d0a490c32))
# [6.14.0](https://git.datacontroller.io/dc/dc/compare/v6.13.2...v6.14.0) (2025-02-26)
### Features
* uses SORTSEQ=LINGUISTIC for the services/metanav/metadetails service ([a45f5bb](https://git.datacontroller.io/dc/dc/commit/a45f5bb3b27a86da5f55ff28c9c7669956484ddf))
## [6.13.2](https://git.datacontroller.io/dc/dc/compare/v6.13.1...v6.13.2) (2025-02-26)
### Bug Fixes
* get metadata email if exists ([1bd0eef](https://git.datacontroller.io/dc/dc/commit/1bd0eef913593579771c647d80010ce628c00819))
## [6.13.1](https://git.datacontroller.io/dc/dc/compare/v6.13.0...v6.13.1) (2025-02-18)
### Bug Fixes
* Avoiding LATIN1 unprintables in various UI locations ([bce1fd5](https://git.datacontroller.io/dc/dc/commit/bce1fd57ef397cfdd030552c3f424a8407174729))
* updated @sasjs/adapter, crypto-browserify ([4e64f28](https://git.datacontroller.io/dc/dc/commit/4e64f28732868b07ec2ab403912bd384c62c7e1d))
# [6.13.0](https://git.datacontroller.io/dc/dc/compare/v6.12.3...v6.13.0) (2025-01-31)
### Bug Fixes
* editor page csv upload ([217220f](https://git.datacontroller.io/dc/dc/commit/217220ffaaf688133321cc68d770aaf1e50590a9))
### Features
* csv test ([c53ab85](https://git.datacontroller.io/dc/dc/commit/c53ab85107f10c023117a099cc06321afc3e1f03))
## [6.12.3](https://git.datacontroller.io/dc/dc/compare/v6.12.2...v6.12.3) (2025-01-27)
### Bug Fixes
* adding missing=STRING to three services ([30d5e51](https://git.datacontroller.io/dc/dc/commit/30d5e51d0b9cf27774038476bd90559600952304))
## [6.12.2](https://git.datacontroller.io/dc/dc/compare/v6.12.1...v6.12.2) (2025-01-27)
### Bug Fixes
* unnecessary zeros when adding new row (data schema default values) ([a1a9051](https://git.datacontroller.io/dc/dc/commit/a1a90519c535ca25e00822b4d3358c991ac9662e))
## [6.12.1](https://git.datacontroller.io/dc/dc/compare/v6.12.0...v6.12.1) (2024-12-31)
### Bug Fixes
* no upcase of pk fields in MPE_TABLES in delete scenario ([3de095f](https://git.datacontroller.io/dc/dc/commit/3de095fe7797cde60f0e232c188305fe423c27eb)), closes [#134](https://git.datacontroller.io/dc/dc/issues/134)
* reduce length of tmp table names. Closes [#130](https://git.datacontroller.io/dc/dc/issues/130) ([f9c2491](https://git.datacontroller.io/dc/dc/commit/f9c2491ab6e7b528b7ffc011fd9e45c963c5f6bf))
# [6.12.0](https://git.datacontroller.io/dc/dc/compare/v6.11.1...v6.12.0) (2024-09-02)
### Bug Fixes
* added appLoc to the system page ([dd2138a](https://git.datacontroller.io/dc/dc/commit/dd2138ac5e6067de310e83d16fccc9b9764ba3ff))
* bumping core for passthrough fix, [#124](https://git.datacontroller.io/dc/dc/issues/124) ([caa9854](https://git.datacontroller.io/dc/dc/commit/caa9854ff0431ccbb6ff1d6d3509dc877362cceb))
* excel with password flow, introducing web worker for XLSX.read ([a3ce367](https://git.datacontroller.io/dc/dc/commit/a3ce36795007a4e3b6ac3499ffd119dc3758f387))
* implemented the new request wrapper usage, added XLSX read with a Web Worker, multi load preview data, full height ([4218da9](https://git.datacontroller.io/dc/dc/commit/4218da91cd193aa45346ad7e34ccc00ca89df4fb))
* **multi load:** xlsx read file ahead of time, while user choose datasets ([6547461](https://git.datacontroller.io/dc/dc/commit/65474616379e1dacc1329b3bdc5eb14f34428bb1))
* refactored adapter request wrapper function to return job log as well ([67436f4](https://git.datacontroller.io/dc/dc/commit/67436f4ff9bb4d77d5f897f47a3e3d472981f275))
* using temporary names for temporary tables ([ce50365](https://git.datacontroller.io/dc/dc/commit/ce503653cd9fc36f72fb172bd14816e07c792e14)), closes [#124](https://git.datacontroller.io/dc/dc/issues/124)
### Features
* searching data in excel files using new algorithm (massive performance improvement) ([bbb725c](https://git.datacontroller.io/dc/dc/commit/bbb725c64cc23ed701b189623992408c42fdde8f))
## [6.11.1](https://git.datacontroller.io/dc/dc/compare/v6.11.0...v6.11.1) (2024-07-02)
### Bug Fixes
* adding SYSSITE, part of [#116](https://git.datacontroller.io/dc/dc/issues/116) ([a156c01](https://git.datacontroller.io/dc/dc/commit/a156c0111b3de5e3744e38d377d6e9aa09915803))
* ensuring review_reason_txt in output. Closes [#117](https://git.datacontroller.io/dc/dc/issues/117) ([e5d93fd](https://git.datacontroller.io/dc/dc/commit/e5d93fd7d6d86bc47ff56664bd812b4d9d0749a5))
# [6.11.0](https://git.datacontroller.io/dc/dc/compare/v6.10.1...v6.11.0) (2024-06-27)
### Bug Fixes
* addressing PR comments ([d94df7f](https://git.datacontroller.io/dc/dc/commit/d94df7f0ebae8feab5e1d5cf8011af8c8be2ca18))
* **multi load:** fixed parsing algorithm reused for the multi load, the fix affects the normal upload as well. ([d4fee79](https://git.datacontroller.io/dc/dc/commit/d4fee791a72021e449cf9680c3e3a525dce41ac1))
* **multi load:** label rename ([fa04d7b](https://git.datacontroller.io/dc/dc/commit/fa04d7bf4e5ba337146bdaa926c60488f8851449))
### Features
* **multi load:** added HOT for user datasets input ([18363bb](https://git.datacontroller.io/dc/dc/commit/18363bbbeb9cf96183ba4841da8134b2f66f735c))
* **multi load:** implemented matching libds and parsing of the multiple sheets ([efcdc69](https://git.datacontroller.io/dc/dc/commit/efcdc694dd275cdb9a4e19f26e5522b8dadc5fd9))
* **multi load:** licence submit limits ([cffeab8](https://git.datacontroller.io/dc/dc/commit/cffeab813d8d4b324f82710dfd73953d4cbf8ffe))
* **multi load:** multiple csv files ([4d27665](https://git.datacontroller.io/dc/dc/commit/4d276657b35a147a2233a03afcb1716348555f52))
* **multi load:** refactored range find function, unlocking excel with password is reusable ([eb7c443](https://git.datacontroller.io/dc/dc/commit/eb7c44333c865e7f7bbfb54dd7f73bfc110f86a7))
* **multi load:** submitting multiple found tables at once ([5deba44](https://git.datacontroller.io/dc/dc/commit/5deba44d2b7352866d821b70dbbfbbf54955dc47))
## [6.10.1](https://git.datacontroller.io/dc/dc/compare/v6.10.0...v6.10.1) (2024-06-07)
### Bug Fixes
* adding 60 more colours to crayons table. Closes [#112](https://git.datacontroller.io/dc/dc/issues/112) ([3521579](https://git.datacontroller.io/dc/dc/commit/3521579dead089eebf62455686be3aee88bde687))
* terms and conditions colours, editor on smaller screens show only icons ([e32d44b](https://git.datacontroller.io/dc/dc/commit/e32d44b1bcdfeea43d19b21ec0ddf4af1ce3992a))
# [6.10.0](https://git.datacontroller.io/dc/dc/compare/v6.9.0...v6.10.0) (2024-06-07)
### Features
* updated handsontable to v14 ([2f8d0b7](https://git.datacontroller.io/dc/dc/commit/2f8d0b764a957ad8c11cd1088fad5e0670aa1731))
# [6.9.0](https://git.datacontroller.io/dc/dc/compare/v6.8.5...v6.9.0) (2024-05-31)
### Bug Fixes
* added colors.scss file, start of a refactor ([110ad9a](https://git.datacontroller.io/dc/dc/commit/110ad9a6e9ed39bd5591ae65c2d0005ba47ca758))
* added stealFocus directive ([9a79f37](https://git.datacontroller.io/dc/dc/commit/9a79f37bf143a1e05df7407358e2687c678e3e68))
### Features
* added app settings service to handle theme persistance, fix: optimised dark mode contrast ([35844e0](https://git.datacontroller.io/dc/dc/commit/35844e0cf1a639553269f2ab0f8666a56ab5cc47))
* **dark mode:** clarity optimizations ([afa7e38](https://git.datacontroller.io/dc/dc/commit/afa7e380aa3bdabd380c038522b9d73d9a8a3b91))
* **dark mode:** lineage and metadata ([27907ed](https://git.datacontroller.io/dc/dc/commit/27907ed00fe81f4c752ffe99d2fb029d5c884f0a))
* **dark mode:** refactoring clarity to enable dark mode, added toggle button ([5564aea](https://git.datacontroller.io/dc/dc/commit/5564aea9c25f8e81ff85afa8352325b9992e4043))
* **dark mode:** removing custom css rules so clarity can handle dark/light modes. Handsontable css for dark mode ([2c0afd0](https://git.datacontroller.io/dc/dc/commit/2c0afd02684cdf3bda374731b0359665e00ed95d))
## [6.8.5](https://git.datacontroller.io/dc/dc/compare/v6.8.4...v6.8.5) (2024-05-23)
### Bug Fixes
* bitemporal load issue [#105](https://git.datacontroller.io/dc/dc/issues/105) ([967698e](https://git.datacontroller.io/dc/dc/commit/967698e4ce1e0abcbc6f0aff8a4be6c512dee93c))
## [6.8.4](https://git.datacontroller.io/dc/dc/compare/v6.8.3...v6.8.4) (2024-05-22)
### Bug Fixes
* new approach to fixing [#105](https://git.datacontroller.io/dc/dc/issues/105) ([c11bd9a](https://git.datacontroller.io/dc/dc/commit/c11bd9a2c55e49f10451962cb2e222c21206bce5))
## [6.8.3](https://git.datacontroller.io/dc/dc/compare/v6.8.2...v6.8.3) (2024-05-09)
### Bug Fixes
* updating core to increase filename length, closes [#103](https://git.datacontroller.io/dc/dc/issues/103) ([ee58fd5](https://git.datacontroller.io/dc/dc/commit/ee58fd5b4bc0dd3e3f232c4f26bb85b2e7fe2b54))
## [6.8.2](https://git.datacontroller.io/dc/dc/compare/v6.8.1...v6.8.2) (2024-05-03)
### Bug Fixes
* dc_request_logs option feature ([93758ef](https://git.datacontroller.io/dc/dc/commit/93758efb275966c181f1ee8b6c752010909a0282))
* release process ([c0dc919](https://git.datacontroller.io/dc/dc/commit/c0dc9191e3b95ea6f7e5021fc0bdbcab0af4cc64))
## [6.8.1](https://git.datacontroller.io/dc/dc/compare/v6.8.0...v6.8.1) (2024-05-02)
### Bug Fixes
* hide approve button when table revertable ([ec0f539](https://git.datacontroller.io/dc/dc/commit/ec0f539a337b176c83a661ff520a6892d47efa02))
# [6.8.0](https://git.datacontroller.io/dc/dc/compare/v6.7.0...v6.8.0) (2024-05-02)
### Bug Fixes
* ci sheet lib, submit message auto focus ([c5e4650](https://git.datacontroller.io/dc/dc/commit/c5e46503272f3f3d9cd83ac04225babf79d4de44))
* **clarity:** new version style issues ([8c7de5a](https://git.datacontroller.io/dc/dc/commit/8c7de5aad7e7e32a64769696af9b93eb9a6225d3))
* cypress tests ([3dd85cc](https://git.datacontroller.io/dc/dc/commit/3dd85cc60bd5ac99bc930b6b9c89a8e707e4d51d))
* ensuring that only restorable versions are restorable ([a402856](https://git.datacontroller.io/dc/dc/commit/a4028562ce91b32ff971ab9821328b97cd23f381))
* ensuring version history only includes loaded versions ([51ebd25](https://git.datacontroller.io/dc/dc/commit/51ebd25aa362aa8e66c83b29b2c64aa0f206f5bd))
* final testing on restore feature ([297a84d](https://git.datacontroller.io/dc/dc/commit/297a84d3a4ebb47bef7f3ca9758978d727afed8d))
* issue with multiple adds/deletes, [#84](https://git.datacontroller.io/dc/dc/issues/84) ([904ca30](https://git.datacontroller.io/dc/dc/commit/904ca30f918da085fa05dae066367b512933d1a9))
* load_ref var ([aaad9f7](https://git.datacontroller.io/dc/dc/commit/aaad9f7207115599a006980fff099d59738dd2cd))
* removing alerts dummy data, closes [#93](https://git.datacontroller.io/dc/dc/issues/93) ([eba21e9](https://git.datacontroller.io/dc/dc/commit/eba21e96b4fa34e63b4477281f47d9a01d621f2e))
* restore table version improvement ([549f357](https://git.datacontroller.io/dc/dc/commit/549f35766ba7b5bbe55694845e85bfefc4193375))
* **sas:** viewer versions fix ([c6595c1](https://git.datacontroller.io/dc/dc/commit/c6595c1f618803d9202cba1a1fe76986449cf2e2))
* stage and approve buttons renaming ([ef81e33](https://git.datacontroller.io/dc/dc/commit/ef81e33f704d0b4f99405d96498e1d29ac817982))
* supporting SCD2 data reversions ([fa8396f](https://git.datacontroller.io/dc/dc/commit/fa8396f0394cbddb6dbacb4b355de078fad49980))
* table info modal, versions - column names ([801c8c6](https://git.datacontroller.io/dc/dc/commit/801c8c6a9fb95388a06a6c6284fec4dc25bb77c5))
* **updates:** angular, clarity, resolved legacy-peer-deps ([c60dd65](https://git.datacontroller.io/dc/dc/commit/c60dd65a1637333f11a0c39ef697c7292a6ede07))
### Features
* backend to show in getchangeinfo whether a user is allowed to restore ([8769841](https://git.datacontroller.io/dc/dc/commit/8769841f08694f672ef7ae1a17beacd0dbedda52))
* list versions of target tables (backend) ([f8a14d4](https://git.datacontroller.io/dc/dc/commit/f8a14d4bdef055b99930491d1f6fabe55a50a497))
* restore ([604c2e7](https://git.datacontroller.io/dc/dc/commit/604c2e70bdeeeb1aa5bb18b94f525ebd049397fa))
* SAS services & tests for RESTORE, [#84](https://git.datacontroller.io/dc/dc/issues/84) ([9ad7ae4](https://git.datacontroller.io/dc/dc/commit/9ad7ae47b5e793ce68ab21c9eeb8dee6cb85e496))
* staging page, restore buttons ([02a8a1c](https://git.datacontroller.io/dc/dc/commit/02a8a1c5654350cafc53b749cceb686fc6848c33))
* table metadata modal, versions tab (and link) ([b27fea5](https://git.datacontroller.io/dc/dc/commit/b27fea5b91e33b4673a3a991aedae558e366ca29))
* **versions:** getting list of versions (plus test) ([8003da9](https://git.datacontroller.io/dc/dc/commit/8003da94e615463ed3ddfd60b0cbf2e58615eab1))
# [6.7.0](https://git.datacontroller.io/dc/dc/compare/v6.6.4...v6.7.0) (2024-04-01)
### Features
* numeric values in hot dropdown aligned right ([9635626](https://git.datacontroller.io/dc/dc/commit/963562621ddf0e8d24a29a8481c5e6da1b040708))
## [6.6.4](https://git.datacontroller.io/dc/dc/compare/v6.6.3...v6.6.4) (2024-04-01)
### Bug Fixes
* ordering SOFTSELECT numerically in dropdown ([f522038](https://git.datacontroller.io/dc/dc/commit/f522038b8ddb1da14b8adbf8346d0a4539a94cc8)), closes [#85](https://git.datacontroller.io/dc/dc/issues/85)
* reverting col ([fbbcf90](https://git.datacontroller.io/dc/dc/commit/fbbcf90956bf538b032b0107c07b8576d20353b9))
* typo ([31d4e5c](https://git.datacontroller.io/dc/dc/commit/31d4e5c727f790d428fb2ea8da60dca929561805))
## [6.6.3](https://git.datacontroller.io/dc/dc/compare/v6.6.2...v6.6.3) (2024-02-26)
### Bug Fixes
* allow empty clause value when NE or CONTAINS ([432450a](https://git.datacontroller.io/dc/dc/commit/432450a15b51a269821ba1d430854f5d1dd04703))
## [6.6.2](https://git.datacontroller.io/dc/dc/compare/v6.6.1...v6.6.2) (2024-02-22)
### Bug Fixes
* excel with commas getting wrapped in quotes ([3860134](https://git.datacontroller.io/dc/dc/commit/38601346a529cfe3787bb286a639e0293c365020))
## [6.6.1](https://git.datacontroller.io/dc/dc/compare/v6.6.0...v6.6.1) (2024-02-19)
### Bug Fixes
* **client:** bumped @sasjs/adapter with fixed redirected login ([eb1c09d](https://git.datacontroller.io/dc/dc/commit/eb1c09d7909ba07faf763da261545dc1efaec1b3))
# [6.6.0](https://git.datacontroller.io/dc/dc/compare/v6.5.2...v6.6.0) (2024-02-12)
### Bug Fixes
* adjust the col numbers in extracted data ([cff5989](https://git.datacontroller.io/dc/dc/commit/cff598955930d2581349e5c6e8b2dd3f9ac96b4c))
### Features
* extra table metadata for [#75](https://git.datacontroller.io/dc/dc/issues/75) ([837821f](https://git.datacontroller.io/dc/dc/commit/837821fd01477d340524dfdaf8dd3d3758cf3095))
* show dsnote on hover title ([6565834](https://git.datacontroller.io/dc/dc/commit/6565834ad4089ecf2de39967e6ed6f217ee4a0a5))
## [6.5.2](https://git.datacontroller.io/dc/dc/compare/v6.5.1...v6.5.2) (2024-02-06)
### Bug Fixes
* ordering mpe_selectbox data by the data values after selectbox_order ([2b54034](https://git.datacontroller.io/dc/dc/commit/2b5403497317632a4be8a00f21455c036f1e6461))
## [6.5.1](https://git.datacontroller.io/dc/dc/compare/v6.5.0...v6.5.1) (2024-02-02)
### Bug Fixes
* ensuring submitter email can be pulled from mpe_emails ([eac0104](https://git.datacontroller.io/dc/dc/commit/eac0104d7aebaf98ff1d1c504c1ce3b25d4a0ce8))
# [6.5.0](https://git.datacontroller.io/dc/dc/compare/v6.4.0...v6.5.0) (2024-01-26)
### Features
* filtering by reference to Variables as well as Values ([6eb1aa8](https://git.datacontroller.io/dc/dc/commit/6eb1aa85d29294d63e6af377e622fbed7fd1fab8))
# [6.4.0](https://git.datacontroller.io/dc/dc/compare/v6.3.1...v6.4.0) (2024-01-24)
### Bug Fixes
* add dcLib to globals ([5d93346](https://git.datacontroller.io/dc/dc/commit/5d93346b52eda27c2829770e96686a713296d373))
* add service to get xlmap rules and fixed interface name ([9ffa30a](https://git.datacontroller.io/dc/dc/commit/9ffa30ab747f5b62acbd452431a5e6e440afcb80))
* increasing length of mpe_excel_map cols to ([2d4d068](https://git.datacontroller.io/dc/dc/commit/2d4d068413dcdac98581f08939e74bde65b73428))
* providing info on mapids to FE ([fd94945](https://git.datacontroller.io/dc/dc/commit/fd94945466c1a797ddc89815258a65624a9cb0cf))
* removing tables from EDIT menu that are in xlmaps ([9550ae4](https://git.datacontroller.io/dc/dc/commit/9550ae4d1154a0272f8a2427ac9d2afdfd699c96))
* removing XLMAP_TARGETLIBDS from mpe_xlmaps_rules table ([93702c6](https://git.datacontroller.io/dc/dc/commit/93702c63dc280cdba1e46f0fd8fe0deaec879611))
* renaming TABLE macvar to LOAD_REF in postdata.sas ([01915a2](https://git.datacontroller.io/dc/dc/commit/01915a2db9a4dfb94e4e8213e2c32181da36d349))
* reverting xlmap in getdata change ([2d6e747](https://git.datacontroller.io/dc/dc/commit/2d6e747db9b84e9fb0dfcf9102a2f7dd2cb51891))
* update edit tab to load ([516e5a2](https://git.datacontroller.io/dc/dc/commit/516e5a206216f79ab1dce9f4eab0d31115743160))
### Features
* adding ability to define the target table for excel maps ([c86fba9](https://git.datacontroller.io/dc/dc/commit/c86fba9dc75ddc6033132f469ad1c31b9131b12e))
* adding ismap attribute to getdata response (and fixing test) ([2702bb3](https://git.datacontroller.io/dc/dc/commit/2702bb3c84c45903def1aa2b8cc20a6dd080281b))
* Complex Excel Uploads ([cf19381](https://git.datacontroller.io/dc/dc/commit/cf193810606f287b8d6f864c4eb64d43c5ab5f3c)), closes [#69](https://git.datacontroller.io/dc/dc/issues/69)
* Create Tables / Files dropdown under load tab ([b473b19](https://git.datacontroller.io/dc/dc/commit/b473b198a61f468dff74cd8e64692e7847084a80))
* display list of maps in sidebar ([5aec024](https://git.datacontroller.io/dc/dc/commit/5aec0242429942f8a989b5fb79f8d3865e9de01a))
* implemented the logic for xlmap component ([50696bb](https://git.datacontroller.io/dc/dc/commit/50696bb926dd00472db65a008771a4b6352871be))
* model changes for [#69](https://git.datacontroller.io/dc/dc/issues/69) ([271543a](https://git.datacontroller.io/dc/dc/commit/271543a446a2116718f99f0540e3cd911f9f5fe7))
* new getxlmaps service to return rules for a particular xlmap_id ([56264ec](https://git.datacontroller.io/dc/dc/commit/56264ecc6908bf6c8e3e666dfeba7068d6195df8))
* validating the excel map after stage (adding load-ref) ([a485c3b](https://git.datacontroller.io/dc/dc/commit/a485c3b78724a36f7bacb264fb02140cc62d6512))
## [6.3.1](https://git.datacontroller.io/dc/dc/compare/v6.3.0...v6.3.1) (2024-01-01)
### Bug Fixes
* enabling excel uploads to tables with retained keys, also adding more validation to MPE_TABLES updates ([3efccc4](https://git.datacontroller.io/dc/dc/commit/3efccc4cf3752763d049836724f2491c287f65db))
# [6.3.0](https://git.datacontroller.io/dc/dc/compare/v6.2.8...v6.3.0) (2023-12-04)
### Features
* viewer row handle ([dadac4f](https://git.datacontroller.io/dc/dc/commit/dadac4f13f85b5446198b6340cad28844defc94d))
## [6.2.8](https://git.datacontroller.io/dc/dc/compare/v6.2.7...v6.2.8) (2023-12-04)
### Bug Fixes
* bumping sasjs/core to fix mp_loadformat issue ([a1d308e](https://git.datacontroller.io/dc/dc/commit/a1d308ea078786b27bf7ec940d018fc657d4c398))
* new logic for -fc suffix. Closes [#63](https://git.datacontroller.io/dc/dc/issues/63) ([5579db0](https://git.datacontroller.io/dc/dc/commit/5579db0eafc668b1bc310099b7cc3062e0598fc4))
## [6.2.7](https://git.datacontroller.io/dc/dc/compare/v6.2.6...v6.2.7) (2023-11-09)
### Bug Fixes
* **audit:** updated crypto-js (hashing rows in dynamic cell validation) ([a7aa42a](https://git.datacontroller.io/dc/dc/commit/a7aa42a59b71597399924b8d2d06010c806321f3))
* missing dependency and avoiding label length limit issue ([91f128c](https://git.datacontroller.io/dc/dc/commit/91f128c2fead1e4f72267d689e67f49ec9a2ab35))
## [6.2.6](https://git.datacontroller.io/dc/dc/compare/v6.2.5...v6.2.6) (2023-10-18)
### Bug Fixes
* bumping core to address mm_assigndirectlib issue ([c27cdab](https://git.datacontroller.io/dc/dc/commit/c27cdab3fccbde814a29424d0344173a73ea816c))
## [6.2.5](https://git.datacontroller.io/dc/dc/compare/v6.2.4...v6.2.5) (2023-10-17)
### Bug Fixes
* enabling AUTHDOMAIN in MM_ASSIGNDIRECTLIB ([008b45a](https://git.datacontroller.io/dc/dc/commit/008b45ad175ec0e6026f5ef3bc210470226e328f))
## [6.2.4](https://git.datacontroller.io/dc/dc/compare/v6.2.3...v6.2.4) (2023-10-16)
### Bug Fixes
* Enable display of metadata-only tables. Closes [#56](https://git.datacontroller.io/dc/dc/issues/56) ([f3e82b4](https://git.datacontroller.io/dc/dc/commit/f3e82b4ee2a9c1c851f812ac60e9eaf05f91a0f9))
## [6.2.3](https://git.datacontroller.io/dc/dc/compare/v6.2.2...v6.2.3) (2023-10-12)
### Bug Fixes
* bumping core library to avoid non-ascii char in mp_validatecols.sas. [#50](https://git.datacontroller.io/dc/dc/issues/50) ([11b06f6](https://git.datacontroller.io/dc/dc/commit/11b06f6416300b6d70b1570c415d5a5c004976db))
* removing copyright symbol from mpe_alerts macro. [#50](https://git.datacontroller.io/dc/dc/issues/50) ([adb7eb7](https://git.datacontroller.io/dc/dc/commit/adb7eb77550c68a2dab15a6ff358129820e9b612))
## [6.2.2](https://git.datacontroller.io/dc/dc/compare/v6.2.1...v6.2.2) (2023-10-09) ## [6.2.2](https://git.datacontroller.io/dc/dc/compare/v6.2.1...v6.2.2) (2023-10-09)

View File

@ -28,5 +28,3 @@ For more information:
* Main site: https://datacontroller.io * Main site: https://datacontroller.io
* Docs: https://docs.datacontroller.io * Docs: https://docs.datacontroller.io
* Code: https://code.datacontroller.io * Code: https://code.datacontroller.io
For support, contact support@4gl.io or reach out on [Matrix](https://matrix.to/#/#dc:4gl.io)!

View File

@ -45,7 +45,6 @@
"numbro", "numbro",
"@clr/icons", "@clr/icons",
"@sasjs/adapter", "@sasjs/adapter",
"@sasjs/utils/types/serverType",
"@sasjs/utils/input/validators", "@sasjs/utils/input/validators",
"@sasjs/utils/utils/bytesToSize", "@sasjs/utils/utils/bytesToSize",
"base64-arraybuffer", "base64-arraybuffer",
@ -68,9 +67,9 @@
"src/styles.scss" "src/styles.scss"
], ],
"scripts": [ "scripts": [
"node_modules/@clr/icons/clr-icons.min.js",
"node_modules/marked/marked.min.js" "node_modules/marked/marked.min.js"
], ]
"webWorkerTsConfig": "tsconfig.worker.json"
}, },
"configurations": { "configurations": {
"production": { "production": {
@ -117,10 +116,10 @@
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"configurations": { "configurations": {
"production": { "production": {
"buildTarget": "datacontroller:build:production" "browserTarget": "datacontroller:build:production"
}, },
"development": { "development": {
"buildTarget": "datacontroller:build:development" "browserTarget": "datacontroller:build:development"
} }
}, },
"defaultConfiguration": "development" "defaultConfiguration": "development"
@ -128,29 +127,31 @@
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"buildTarget": "datacontroller:build" "browserTarget": "datacontroller:build"
} }
}, },
"test": { "test": {
"builder": "@angular-devkit/build-angular:karma", "builder": "@angular-devkit/build-angular:karma",
"options": { "options": {
"tsConfig": "tsconfig.spec.json",
"inlineStyleLanguage": "scss",
"codeCoverage": true,
"polyfills": [ "polyfills": [
"src/polyfills.ts", "src/polyfills.ts",
"zone.js", "zone.js",
"zone.js/testing" "zone.js/testing"
], ],
"tsConfig": "tsconfig.spec.json", "styles": [
"inlineStyleLanguage": "scss", "src/styles.scss"
],
"scripts": [
],
"assets": [ "assets": [
"src/favicon.ico", "src/favicon.ico",
"src/assets" "src/assets"
], ],
"styles": [ "karmaConfig": "karma.conf.js"
"src/styles.scss"
],
"scripts": [],
"karmaConfig": "karma.conf.js",
"webWorkerTsConfig": "tsconfig.worker.json"
} }
}, },
"lint": { "lint": {

View File

@ -9,8 +9,6 @@ export default defineConfig({
html: true, html: true,
json: false, json: false,
}, },
viewportHeight: 900,
viewportWidth: 1600,
chromeWebSecurity: false, chromeWebSecurity: false,
defaultCommandTimeout: 30000, defaultCommandTimeout: 30000,

View File

@ -1,115 +0,0 @@
import { Callbacks } from 'cypress/types/jquery/index'
const username = Cypress.env('username')
const password = Cypress.env('password')
const hostUrl = Cypress.env('hosturl')
const appLocation = Cypress.env('appLocation')
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
const serverType = Cypress.env('serverType')
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
const fixturePath = 'csvs/'
context('excel tests: ', function () {
this.beforeAll(() => {
cy.visit(`${hostUrl}/SASLogon/logout`)
cy.loginAndUpdateValidKey(true)
})
this.beforeEach(() => {
cy.visit(hostUrl + appLocation)
visitPage('home')
colorLog(
`TEST START ---> ${
Cypress.mocha.getRunner().suite.ctx.currentTest.title
}`,
'#3498DB'
)
})
it('1 | Uploads regular csv file', () => {
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
attachExcelFile('regular.csv', () => {
cy.get('#approval-btn', { timeout: 60000 })
.should('be.visible')
// .then(() => {
// cy.get('#hotInstance', { timeout: 30000 })
// .find('div.ht_master.handsontable')
// .find('div.wtHolder')
// .find('div.wtHider')
// .find('div.wtSpreader')
// .find('table.htCore')
// .find('tbody')
// .then((data) => {
// let cell: any = data[0].children[0].children[1]
// expect(cell.innerText).to.equal('0')
// cell = data[0].children[0].children[2]
// expect(cell.innerText).to.equal('44')
// cell = data[0].children[0].children[3]
// expect(cell.innerText).to.equal('abc')
// cell = data[0].children[0].children[6]
// expect(cell.innerText).to.equal('Option abc')
// })
// })
})
})
this.afterEach(() => {
colorLog(`TEST END -------------`, '#3498DB')
})
})
const openTableFromTree = (libNameIncludes: string, tablename: string) => {
cy.get('.app-loading', { timeout: longerCommandTimeout })
.should('not.exist')
.then(() => {
cy.get('.nav-tree clr-tree > clr-tree-node', {
timeout: longerCommandTimeout
}).then((treeNodes: any) => {
let viyaLib
for (let node of treeNodes) {
if (node.innerText.toLowerCase().includes(libNameIncludes)) {
viyaLib = node
break
}
}
cy.get(viyaLib).within(() => {
cy.get('.clr-tree-node-content-container > button').click()
cy.get('.clr-treenode-link').then((innerNodes: any) => {
for (let innerNode of innerNodes) {
if (innerNode.innerText.toLowerCase().includes(tablename)) {
innerNode.click()
break
}
}
})
})
})
})
}
const attachExcelFile = (excelFilename: string, callback?: any) => {
cy.get('.buttonBar button:last-child')
.should('exist')
.click()
.then(() => {
cy.get('input[type="file"]#file-upload')
.attachFile(`/${fixturePath}/${excelFilename}`)
.then(() => {
if (callback) callback()
})
})
}
const visitPage = (url: string) => {
cy.visit(`${hostUrl}${appLocation}/#/${url}`)
}
const colorLog = (msg: string, color: string) => {
console.log('%c' + msg, 'color:' + color + ';font-weight:bold;')
}

View File

@ -15,6 +15,9 @@ context('editor tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -115,6 +118,10 @@ context('editor tests: ', function () {
}) })
}) })
}) })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const clickOnEdit = (callback?: any) => { const clickOnEdit = (callback?: any) => {
@ -214,13 +221,13 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if ( if (
approvalButton.innerText approvalButton.innerText
.toLowerCase() .toLowerCase()
.includes('approve') .includes('go to approvals screen')
) { ) {
approvalButton.click() approvalButton.click()
break break

View File

@ -1,228 +0,0 @@
import { Callbacks } from 'cypress/types/jquery/index'
const username = Cypress.env('username')
const password = Cypress.env('password')
const hostUrl = Cypress.env('hosturl')
const appLocation = Cypress.env('appLocation')
const longerCommandTimeout = Cypress.env('longerCommandTimeout')
const serverType = Cypress.env('serverType')
const libraryToOpenIncludes = Cypress.env(`libraryToOpenIncludes_${serverType}`)
const fixturePath = 'excels_multi_load/'
const library = 'DC996664'
const mpeXTestTable = 'MPE_X_TEST'
const mpeTablesTable = 'MPE_TABLES'
context('excel multi load tests: ', function () {
this.beforeAll(() => {
cy.visit(`${hostUrl}/SASLogon/logout`)
cy.loginAndUpdateValidKey(true)
})
this.beforeEach(() => {
cy.visit(hostUrl + appLocation)
visitPage('home/multi-load')
colorLog(
`TEST START ---> ${
Cypress.mocha.getRunner().suite.ctx.currentTest.title
}`,
'#3498DB'
)
})
it('1 | Uploads Excel file with multiple sheets, 3 sheets including data, 2 sheets matched with dataset', (done) => {
attachExcelFile('multi_load_test_2.xlsx', () => {
checkHotUserDatasetTable('hotTableUserDataset', [
[library, mpeXTestTable],
[library, mpeTablesTable]
], () => {
cy.get('#continue-btn').trigger('click').then(() => {
checkIfTreeHasTables([`${library}.${mpeXTestTable}`, `${library}.${mpeTablesTable}`], undefined, (includes: boolean) => {
if (includes) {
// MPE_TABLES sheet does not have data so 1 error image must be shown
hasErrorTables(1, (valid: boolean) => {
if (valid) done()
})
}
})
})
})
})
})
it('2 | Uploads Excel file with multiple sheets, 2 sheets matched with dataset, 1 matched sheet does not have data', (done) => {
attachExcelFile('multi_load_test_1.xlsx', () => {
checkHotUserDatasetTable('hotTableUserDataset', [
[library, mpeXTestTable],
[library, mpeTablesTable]
], () => {
cy.get('#continue-btn').trigger('click').then(() => {
checkIfTreeHasTables([`${library}.${mpeXTestTable}`, `${library}.${mpeTablesTable}`], `${library}.${mpeXTestTable}`, (includes: boolean) => {
if (includes) {
cy.get('#hotTable').should('be.visible').then(() => {
checkHotUserDatasetTable('hotTable', [
['No', '1', 'more dummy data'],
['No', '1', 'It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:'],
['No', '1', 'if you can fill the unforgiving minute']
], () => {
submitTables()
hasSuccessSubmits(2, (valid: boolean) => {
if (valid) done()
})
})
})
}
})
})
})
})
})
it('3 | Uploads Excel file with multiple sheets, 1 sheets has 2 tables', (done) => {
attachExcelFile('multi_load_test_1.xlsx', () => {
checkHotUserDatasetTable('hotTableUserDataset', [
[library, mpeXTestTable],
[library, mpeTablesTable]
], () => {
cy.get('#continue-btn').trigger('click').then(() => {
checkIfTreeHasTables([`${library}.${mpeXTestTable}`, `${library}.${mpeTablesTable}`], `${library}.${mpeXTestTable}`, (includes: boolean) => {
if (includes) {
cy.get('#hotTable').should('be.visible').then(() => {
checkHotUserDatasetTable('hotTable', [
['No', '1', 'more dummy data'],
['No', '1', 'It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:'],
['No', '1', 'if you can fill the unforgiving minute']
], () => {
clickOnTreeNode('DC996664.MPE_TABLES', () => {
cy.wait(1000).then(() => {
cy.get('#hotTable').should('be.visible').then(() => {
checkHotUserDatasetTable('hotTable', [
['No', 'DC914286', 'MPE_COLUMN_LEVEL_SECURITY'],
['No', 'DC914286', 'MPE_XLMAP_INFO'],
['No', 'DC914286', 'MPE_XLMAP_RULES']
], () => {
submitTables()
hasSuccessSubmits(2, (valid: boolean) => {
if (valid) done()
})
})
})
})
})
})
})
}
})
})
})
})
})
this.afterEach(() => {
colorLog(`TEST END -------------`, '#3498DB')
})
})
const attachExcelFile = (excelFilename: string, callback?: any) => {
cy.get('#browse-file')
.should('exist')
.click()
.then(() => {
cy.get('input[type="file"]#file-upload')
.attachFile(`/${fixturePath}/${excelFilename}`)
.then(() => {
if (callback) callback()
})
})
}
const checkHotUserDatasetTable = (hotId: string, dataToContain: any[][], callback?: () => void) => {
cy.get(`#${hotId}`, { timeout: longerCommandTimeout })
.find('div.ht_master.handsontable')
.find('div.wtHolder')
.find('div.wtHider')
.find('div.wtSpreader')
.find('table.htCore')
.find('tbody')
.then((data) => {
cy.wait(2000).then(() => {
for (let rowI = 0; rowI < dataToContain.length; rowI++) {
for (let colI = 0; colI < dataToContain[rowI].length; colI++) {
expect(data[0].children[rowI].children[colI]).to.contain(dataToContain[rowI][colI])
}
}
if (callback) callback()
})
})
}
const clickOnTreeNode = (clickOnNode: string, callback?: () => void) => {
cy.get('.nav-tree clr-tree > clr-tree-node').then((treeNodes: any) => {
for (let node of treeNodes) {
if (node.innerText.toUpperCase().trim().includes(clickOnNode)) {
cy.get(node).trigger('click')
if (callback) callback()
}
}
})
}
const checkIfTreeHasTables = (tables: string[], clickOnNode?: string, callback?: (includes: boolean) => void) => {
cy.get('.nav-tree clr-tree > clr-tree-node').then((treeNodes: any) => {
let datasets = tables
let nodesCorrect = true
let nodeToClick
for (let node of treeNodes) {
if (!datasets.includes(node.innerText.toUpperCase().trim())) {
nodesCorrect = false
}
if (clickOnNode) {
if (node.innerText.toUpperCase().trim().includes(clickOnNode)) {
nodeToClick = node
}
}
}
if (nodeToClick) {
cy.wait(1000)
cy.get(nodeToClick).trigger('click')
}
if (callback) callback(nodesCorrect)
})
}
const submitTables = () => {
cy.get('#submit-all').trigger('click')
cy.get('#submit-tables').trigger('click')
cy.wait(1000)
}
const hasSuccessSubmits = (expectedNoOfSubmits: number, callback: (valid: boolean) => void) => {
cy.get('.nav-tree clr-tree > clr-tree-node cds-icon[status="success"]').should('be.visible').then(($nodes) => {
callback(expectedNoOfSubmits === $nodes.length)
})
}
const hasErrorTables = (expectedNoOfErrors: number, callback: (valid: boolean) => void) => {
cy.get('.nav-tree clr-tree > clr-tree-node cds-icon[status="danger"]').should('be.visible').then(($nodes) => {
callback(expectedNoOfErrors === $nodes.length)
})
}
const visitPage = (url: string) => {
cy.visit(`${hostUrl}${appLocation}/#/${url}`)
}
const colorLog = (msg: string, color: string) => {
console.log('%c' + msg, 'color:' + color + ';font-weight:bold;')
}

View File

@ -17,6 +17,9 @@ context('excel tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
@ -109,8 +112,13 @@ context('excel tests: ', function () {
openTableFromTree(libraryToOpenIncludes, 'mpe_x_test') openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
attachExcelFile('duplicate_column_excel.xlsx', () => { attachExcelFile('duplicate_column_excel.xlsx', () => {
submitExcel() cy.get('.abortMsg', { timeout: longerCommandTimeout })
rejectExcel(done) .should('exist')
.then((elements: any) => {
if (elements[0]) {
if (elements[0].innerText.toLowerCase().includes('missing')) done()
}
})
}) })
}) })
@ -329,6 +337,7 @@ context('excel tests: ', function () {
this.afterEach(() => { this.afterEach(() => {
colorLog(`TEST END -------------`, '#3498DB') colorLog(`TEST END -------------`, '#3498DB')
// cy.visit(`${hostUrl}/SASLogon/logout`)
}) })
}) })
@ -396,13 +405,13 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if ( if (
approvalButton.innerText approvalButton.innerText
.toLowerCase() .toLowerCase()
.includes('approve') .includes('go to approvals screen')
) { ) {
approvalButton.click() approvalButton.click()
break break
@ -429,13 +438,13 @@ const rejectExcel = (callback?: any) => {
const acceptExcel = (callback?: any) => { const acceptExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if ( if (
approvalButton.innerText approvalButton.innerText
.toLowerCase() .toLowerCase()
.includes('approve') .includes('go to approvals screen')
) { ) {
approvalButton.click() approvalButton.click()
break break

View File

@ -15,7 +15,9 @@ context('filtering tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout }) cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout })
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -157,21 +159,24 @@ context('filtering tests: ', function () {
}) })
}) })
// TODO: fix it('7 | filter bestnum field BETWEEN', (done) => {
// it('7 | filter bestnum field BETWEEN', (done) => { openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
// openTableFromTree(libraryToOpenIncludes, 'mpe_x_test')
// openFilterPopup(() => { openFilterPopup(() => {
// setFilterWithValue('SOME_BESTNUM', '0-10', 'between', () => { setFilterWithValue('SOME_BESTNUM', '0-10', 'between', () => {
// checkInfoBarIncludes( checkInfoBarIncludes(
// `AND,AND,0,SOME_BESTNUM,BETWEEN,0 AND 10`, `AND,AND,0,SOME_BESTNUM,BETWEEN,0 AND 10`,
// (includes: boolean) => { (includes: boolean) => {
// if (includes) done() if (includes) done()
// } }
// ) )
// }) })
// }) })
// }) })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const checkInfoBarIncludes = (text: string, callback: any) => { const checkInfoBarIncludes = (text: string, callback: any) => {

View File

@ -23,12 +23,15 @@ interface EditConfigTableCells {
context('licensing tests: ', function () { context('licensing tests: ', function () {
this.beforeAll(() => { this.beforeAll(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
cy.loginAndUpdateValidKey() cy.loginAndUpdateValidKey()
}) })
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -372,7 +375,9 @@ context('licensing tests: ', function () {
}) })
} }
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const logout = (callback?: any) => { const logout = (callback?: any) => {
@ -694,13 +699,13 @@ const submitTable = (callback?: any) => {
const approveTable = (callback?: any) => { const approveTable = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if ( if (
approvalButton.innerText approvalButton.innerText
.toLowerCase() .toLowerCase()
.includes('approve') .includes('go to approvals screen')
) { ) {
approvalButton.click() approvalButton.click()
break break

View File

@ -18,6 +18,9 @@ context('liveness tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -122,13 +125,13 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if ( if (
approvalButton.innerText approvalButton.innerText
.toLowerCase() .toLowerCase()
.includes('approve') .includes('go to approvals screen')
) { ) {
approvalButton.click() approvalButton.click()
break break

View File

@ -16,6 +16,7 @@ context('editor tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
cy.wait(2000) cy.wait(2000)
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -392,6 +393,10 @@ context('editor tests: ', function () {
// } // }
// ) // )
// }) // })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const removeAllColumns = () => { const removeAllColumns = () => {

View File

@ -1,497 +0,0 @@
PRIMARY_KEY_FIELD,SOME_CHAR,SOME_DROPDOWN,SOME_NUM,SOME_DATE,SOME_DATETIME,SOME_TIME,SOME_SHORTNUM,SOME_BESTNUM
0,abc,Option abc,42,12FEB1960,01JAN1960:00:00:42,0:00:42,3,44
1,more dummy data,Option 2,42,12FEB1960,01JAN1960:00:00:42,0:07:02,3,44
2,even more dummy data,Option 3,42,12FEB1960,01JAN1960:00:00:42,0:02:22,3,44
3,"It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told:",Option 2,1613.001,27FEB1961,01JAN1960:00:07:03,0:00:44,3,44
4,if you can fill the unforgiving minute,Option 1,1613.0011235,02AUG1971,29MAY1973:06:12:03,0:06:52,3,44
1010,10 bottles of beer on the wall,Option 1,0.9153696885,04MAR1962,01JAN1960:12:47:55,0:01:40,92,76
1011,11 bottles of beer on the wall,Option 1,0.3531217558,29MAR1960,01JAN1960:03:33:24,0:01:03,80,29
1012,12 bottles of beer on the wall,Option 1,0.6743748717,02AUG1962,01JAN1960:07:25:59,0:00:10,16,98
1013,13 bottles of beer on the wall,Option 1,0.1305445992,11SEP1960,01JAN1960:13:51:32,0:00:35,73,15
1014,14 bottles of beer on the wall,Option 1,0.7409067949,26JUL1960,01JAN1960:05:18:10,0:00:41,30,89
1015,15 bottles of beer on the wall,Option 1,0.0869016028,28FEB1961,01JAN1960:13:23:45,0:00:44,80,3
1016,16 bottles of beer on the wall,Option 1,0.0462121419,09AUG1962,01JAN1960:07:42:38,0:01:17,62,2
1017,17 bottles of beer on the wall,Option 1,0.7501918947,14MAY1962,01JAN1960:04:40:20,0:00:15,53,65
1018,18 bottles of beer on the wall,Option 1,0.7300173294,03AUG1962,01JAN1960:03:20:41,0:00:41,21,60
1019,19 bottles of beer on the wall,Option 1,0.6960950437,01JUN1960,01JAN1960:01:58:52,0:01:08,38,5
1020,20 bottles of beer on the wall,Option 1,0.6190566065,30MAY1961,01JAN1960:09:04:20,0:01:07,92,23
1021,21 bottles of beer on the wall,Option 1,0.5173368238,07JAN1961,01JAN1960:07:52:34,0:00:52,57,21
1022,22 bottles of beer on the wall,Option 1,0.4720626452,07NOV1960,01JAN1960:12:12:00,0:00:26,53,32
1023,23 bottles of beer on the wall,Option 1,0.2856596393,08AUG1960,01JAN1960:06:09:25,0:00:28,40,12
1024,24 bottles of beer on the wall,Option 1,0.5160869418,02JUN1960,01JAN1960:06:36:06,0:01:10,41,81
1025,25 bottles of beer on the wall,Option 1,0.1683158517,05JAN1961,01JAN1960:08:14:35,0:00:06,18,53
1026,26 bottles of beer on the wall,Option 1,0.8951142248,28NOV1961,01JAN1960:03:31:17,0:00:58,79,54
1027,27 bottles of beer on the wall,Option 1,0.7037817481,01SEP1961,01JAN1960:05:48:34,0:00:29,50,15
1028,28 bottles of beer on the wall,Option 1,0.6193826714,31MAR1962,01JAN1960:02:49:39,0:00:24,78,87
1029,29 bottles of beer on the wall,Option 1,0.9339028457,06DEC1961,01JAN1960:02:57:57,0:00:24,73,64
1030,30 bottles of beer on the wall,Option 1,0.5647351339,10AUG1960,01JAN1960:11:02:59,0:00:55,39,28
1031,31 bottles of beer on the wall,Option 1,0.1218988607,19JUN1961,01JAN1960:04:19:32,0:00:58,51,32
1032,32 bottles of beer on the wall,Option 1,0.3459929113,14MAY1962,01JAN1960:05:42:48,0:00:54,96,46
1033,33 bottles of beer on the wall,Option 1,0.092664999,31AUG1962,01JAN1960:00:08:34,0:00:51,69,90
1034,34 bottles of beer on the wall,Option 1,0.9793458097,08FEB1960,01JAN1960:01:55:23,0:00:42,45,28
1035,35 bottles of beer on the wall,Option 1,0.8964386624,18DEC1961,01JAN1960:04:42:45,0:00:07,49,97
1036,36 bottles of beer on the wall,Option 1,0.0961652911,13NOV1960,01JAN1960:03:44:53,0:01:25,62,59
1037,37 bottles of beer on the wall,Option 1,0.3475089201,16JAN1962,01JAN1960:01:35:19,0:00:15,23,50
1038,38 bottles of beer on the wall,Option 1,0.3096271312,21MAY1960,01JAN1960:09:51:33,0:00:15,2,71
1039,39 bottles of beer on the wall,Option 1,0.9445223114,28AUG1962,01JAN1960:07:09:31,0:00:12,30,31
1040,40 bottles of beer on the wall,Option 1,0.5626084667,06NOV1960,01JAN1960:01:42:16,0:01:14,18,97
1041,41 bottles of beer on the wall,Option 1,0.9432962513,01JUN1962,01JAN1960:03:30:04,0:00:11,20,34
1042,42 bottles of beer on the wall,Option 1,0.5802429382,08JUL1961,01JAN1960:08:12:43,0:01:26,18,5
1043,43 bottles of beer on the wall,Option 1,0.1970176255,27MAR1961,01JAN1960:00:19:45,0:01:29,13,76
1044,44 bottles of beer on the wall,Option 1,0.4980671608,05JAN1961,01JAN1960:13:36:08,0:00:56,4,36
1045,45 bottles of beer on the wall,Option 1,0.2486515531,05MAY1962,01JAN1960:08:47:09,0:00:42,2,23
1046,46 bottles of beer on the wall,Option 1,0.4097825794,20JUN1960,01JAN1960:03:33:26,0:00:31,98,71
1047,47 bottles of beer on the wall,Option 1,0.138754441,28JAN1960,01JAN1960:00:57:41,0:00:18,80,32
1048,48 bottles of beer on the wall,Option 1,0.0249874415,03MAR1960,01JAN1960:11:33:53,0:00:04,96,76
1049,49 bottles of beer on the wall,Option 1,0.8395310011,06NOV1961,01JAN1960:09:54:04,0:00:52,28,45
1050,50 bottles of beer on the wall,Option 1,0.0942291618,14APR1962,01JAN1960:08:09:30,0:01:36,37,86
1051,51 bottles of beer on the wall,Option 1,0.1670458001,13NOV1961,01JAN1960:01:05:55,0:00:25,42,83
1052,52 bottles of beer on the wall,Option 1,0.3122402715,04JUN1960,01JAN1960:03:47:47,0:01:01,18,78
1053,53 bottles of beer on the wall,Option 1,0.3854694261,14JUN1960,01JAN1960:02:43:08,0:00:06,22,67
1054,54 bottles of beer on the wall,Option 1,0.1950434345,14NOV1961,01JAN1960:02:46:34,0:00:55,42,0
1055,55 bottles of beer on the wall,Option 1,0.4948673586,29MAR1962,01JAN1960:00:48:06,0:01:04,28,4
1056,56 bottles of beer on the wall,Option 1,0.6464513832,06SEP1962,01JAN1960:10:08:36,0:01:02,43,82
1057,57 bottles of beer on the wall,Option 1,0.0724864798,20JUN1961,01JAN1960:12:22:51,0:01:27,82,53
1058,58 bottles of beer on the wall,Option 1,0.8114467793,20MAR1962,01JAN1960:06:11:33,0:01:29,40,89
1059,59 bottles of beer on the wall,Option 1,0.6348024321,28JUN1962,01JAN1960:05:21:21,0:01:37,55,41
1060,60 bottles of beer on the wall,Option 1,0.8019492933,08APR1961,01JAN1960:12:37:00,0:01:29,49,88
1061,61 bottles of beer on the wall,Option 1,0.4695742002,29JAN1962,01JAN1960:08:54:24,0:00:15,40,91
1062,62 bottles of beer on the wall,Option 1,0.902706475,15JUN1961,01JAN1960:09:46:49,0:00:23,74,70
1063,63 bottles of beer on the wall,Option 1,0.4557614594,16JUL1961,01JAN1960:02:06:05,0:01:09,7,3
1064,64 bottles of beer on the wall,Option 1,0.6632444466,20MAY1961,01JAN1960:02:44:44,0:00:20,42,100
1065,65 bottles of beer on the wall,Option 1,0.3901674,31AUG1961,01JAN1960:07:56:49,0:00:32,98,3
1066,66 bottles of beer on the wall,Option 1,0.8453234848,30JUN1962,01JAN1960:04:51:54,0:01:02,51,22
1067,67 bottles of beer on the wall,Option 1,0.9370150906,26APR1960,01JAN1960:04:05:08,0:01:39,28,86
1068,68 bottles of beer on the wall,Option 1,0.8854161277,22MAR1962,01JAN1960:10:38:49,0:01:07,60,85
1069,69 bottles of beer on the wall,Option 1,0.1327841906,24MAY1960,01JAN1960:01:18:46,0:01:15,88,85
1070,70 bottles of beer on the wall,Option 1,0.5846563226,27JUL1962,01JAN1960:03:52:31,0:00:09,20,8
1071,71 bottles of beer on the wall,Option 1,0.0257193684,18FEB1961,01JAN1960:03:25:01,0:00:29,1,62
1072,72 bottles of beer on the wall,Option 1,0.9471486034,01JUN1962,01JAN1960:04:05:25,0:01:22,65,20
1073,73 bottles of beer on the wall,Option 1,0.3037446282,16MAY1962,01JAN1960:05:10:19,0:00:01,14,34
1074,74 bottles of beer on the wall,Option 1,0.2508690675,01NOV1961,01JAN1960:11:26:03,0:00:15,8,74
1075,75 bottles of beer on the wall,Option 1,0.814380363,17SEP1960,01JAN1960:09:00:38,0:00:25,95,1
1076,76 bottles of beer on the wall,Option 1,0.3761493621,16AUG1961,01JAN1960:01:48:17,0:00:52,5,38
1077,77 bottles of beer on the wall,Option 1,0.3621215761,25JUL1961,01JAN1960:11:48:47,0:01:20,86,90
1078,78 bottles of beer on the wall,Option 1,0.0268799584,20MAY1961,01JAN1960:12:43:34,0:01:00,70,96
1079,79 bottles of beer on the wall,Option 1,0.4112483945,27JUL1962,01JAN1960:01:20:24,0:01:26,66,20
1080,80 bottles of beer on the wall,Option 1,0.9501868011,15APR1961,01JAN1960:09:58:20,0:00:51,93,79
1081,81 bottles of beer on the wall,Option 1,0.9866548018,13SEP1961,01JAN1960:05:20:04,0:00:14,28,97
1082,82 bottles of beer on the wall,Option 1,0.9907830073,22FEB1962,01JAN1960:03:29:03,0:00:17,16,91
1083,83 bottles of beer on the wall,Option 1,0.8927816567,11MAR1960,01JAN1960:05:52:48,0:01:26,54,14
1084,84 bottles of beer on the wall,Option 1,0.12871663,02FEB1961,01JAN1960:10:34:37,0:00:44,52,90
1085,85 bottles of beer on the wall,Option 1,0.5490252802,02JAN1960,01JAN1960:06:11:58,0:00:27,4,98
1086,86 bottles of beer on the wall,Option 1,0.5432773864,11FEB1960,01JAN1960:08:40:00,0:01:15,79,19
1087,87 bottles of beer on the wall,Option 1,0.8223943137,01OCT1960,01JAN1960:08:11:33,0:01:19,2,86
1088,88 bottles of beer on the wall,Option 1,0.8496777699,09FEB1962,01JAN1960:03:10:35,0:00:15,95,6
1089,89 bottles of beer on the wall,Option 1,0.9308730536,27MAY1962,01JAN1960:11:57:53,0:01:18,86,90
1090,90 bottles of beer on the wall,Option 1,0.3072653344,23FEB1962,01JAN1960:04:52:38,0:00:25,85,17
1091,91 bottles of beer on the wall,Option 1,0.7687679575,12FEB1960,01JAN1960:08:47:11,0:01:20,8,7
1092,92 bottles of beer on the wall,Option 1,0.1873595105,29SEP1961,01JAN1960:04:29:58,0:00:29,17,78
1093,93 bottles of beer on the wall,Option 1,0.0495966631,03OCT1961,01JAN1960:03:18:50,0:00:39,89,56
1094,94 bottles of beer on the wall,Option 1,0.2607690526,19SEP1960,01JAN1960:03:22:28,0:00:29,81,16
1095,95 bottles of beer on the wall,Option 1,0.549640266,07JUN1962,01JAN1960:06:15:32,0:00:04,57,70
1096,96 bottles of beer on the wall,Option 1,0.9993291092,08MAR1961,01JAN1960:13:49:08,0:00:33,37,28
1097,97 bottles of beer on the wall,Option 1,0.9517237963,02SEP1960,01JAN1960:05:16:03,0:00:40,77,61
1098,98 bottles of beer on the wall,Option 1,0.5952155588,14FEB1962,01JAN1960:05:05:11,0:01:29,63,83
1099,99 bottles of beer on the wall,Option 1,0.7526210732,05MAY1961,01JAN1960:06:58:36,0:00:02,95,1
10100,100 bottles of beer on the wall,Option 1,0.307558153,17MAY1961,01JAN1960:06:13:01,0:01:37,68,7
10101,101 bottles of beer on the wall,Option 1,0.6596710829,15APR1962,01JAN1960:08:34:02,0:00:43,66,43
10102,102 bottles of beer on the wall,Option 1,0.0202811998,31AUG1961,01JAN1960:07:22:35,0:01:31,57,35
10103,103 bottles of beer on the wall,Option 1,0.6699061034,02MAY1962,01JAN1960:05:13:17,0:00:36,30,23
10104,104 bottles of beer on the wall,Option 1,0.330972748,04JUN1961,01JAN1960:06:47:20,0:01:05,69,82
10105,105 bottles of beer on the wall,Option 1,0.2274839176,25JAN1961,01JAN1960:05:34:51,0:00:56,63,68
10106,106 bottles of beer on the wall,Option 1,0.5612243989,27JUN1962,01JAN1960:04:32:03,0:01:15,19,73
10107,107 bottles of beer on the wall,Option 1,0.7398902111,03SEP1962,01JAN1960:08:34:07,0:00:17,90,6
10108,108 bottles of beer on the wall,Option 1,0.6124899791,08AUG1960,01JAN1960:04:59:34,0:00:25,56,12
10109,109 bottles of beer on the wall,Option 1,0.882404773,26JAN1961,01JAN1960:01:29:15,0:01:26,36,4
10110,110 bottles of beer on the wall,Option 1,0.4427004733,27FEB1961,01JAN1960:06:16:49,0:01:40,97,84
10111,111 bottles of beer on the wall,Option 1,0.3609524622,10JAN1962,01JAN1960:09:48:37,0:01:11,87,62
10112,112 bottles of beer on the wall,Option 1,0.9408929562,03AUG1960,01JAN1960:06:54:26,0:00:08,19,33
10113,113 bottles of beer on the wall,Option 1,0.3149107319,10AUG1962,01JAN1960:13:01:00,0:00:04,75,60
10114,114 bottles of beer on the wall,Option 1,0.0525069181,17APR1962,01JAN1960:13:00:52,0:00:35,9,23
10115,115 bottles of beer on the wall,Option 1,0.145448105,14FEB1962,01JAN1960:04:06:08,0:00:26,45,91
10116,116 bottles of beer on the wall,Option 1,0.2444279959,10OCT1961,01JAN1960:08:03:12,0:01:37,12,41
10117,117 bottles of beer on the wall,Option 1,0.4619846043,30JUL1960,01JAN1960:09:40:16,0:00:50,2,88
10118,118 bottles of beer on the wall,Option 1,0.0316203502,13JUL1961,01JAN1960:08:31:39,0:01:05,60,94
10119,119 bottles of beer on the wall,Option 1,0.4738720574,13AUG1960,01JAN1960:01:31:05,0:01:17,43,79
10120,120 bottles of beer on the wall,Option 1,0.8058761856,11JUN1960,01JAN1960:12:56:35,0:00:08,92,36
10121,121 bottles of beer on the wall,Option 1,0.2955600979,08JUL1962,01JAN1960:06:09:22,0:00:03,94,80
10122,122 bottles of beer on the wall,Option 1,0.0064115427,18SEP1962,01JAN1960:00:06:24,0:00:13,72,75
10123,123 bottles of beer on the wall,Option 1,0.5678159327,21APR1960,01JAN1960:10:54:21,0:00:16,75,67
10124,124 bottles of beer on the wall,Option 1,0.1431510994,10JAN1962,01JAN1960:01:57:00,0:00:12,48,31
10125,125 bottles of beer on the wall,Option 1,0.3805634409,26JAN1962,01JAN1960:03:03:19,0:01:29,83,52
10126,126 bottles of beer on the wall,Option 1,0.3833517993,26APR1960,01JAN1960:11:27:41,0:00:44,99,36
10127,127 bottles of beer on the wall,Option 1,0.5669089111,04MAR1961,01JAN1960:05:36:22,0:01:18,43,27
10128,128 bottles of beer on the wall,Option 1,0.1514211843,01NOV1960,01JAN1960:07:45:50,0:01:02,22,12
10129,129 bottles of beer on the wall,Option 1,0.0446588583,05JAN1961,01JAN1960:02:13:55,0:00:42,27,46
10130,130 bottles of beer on the wall,Option 1,0.7892141611,22APR1962,01JAN1960:04:17:54,0:01:05,75,84
10131,131 bottles of beer on the wall,Option 1,0.5012088001,24DEC1960,01JAN1960:13:03:23,0:01:22,87,82
10132,132 bottles of beer on the wall,Option 1,0.2327582944,07APR1961,01JAN1960:01:33:15,0:01:14,18,46
10133,133 bottles of beer on the wall,Option 1,0.2234651173,20MAR1961,01JAN1960:13:52:02,0:01:06,42,58
10134,134 bottles of beer on the wall,Option 1,0.4954405918,10FEB1961,01JAN1960:13:51:14,0:01:36,35,11
10135,135 bottles of beer on the wall,Option 1,0.7874922891,15AUG1960,01JAN1960:00:21:57,0:00:52,45,36
10136,136 bottles of beer on the wall,Option 1,0.3992494891,06SEP1961,01JAN1960:09:51:46,0:01:25,26,9
10137,137 bottles of beer on the wall,Option 1,0.3964866136,25MAY1960,01JAN1960:03:19:48,0:00:28,44,3
10138,138 bottles of beer on the wall,Option 1,0.9466173323,06APR1962,01JAN1960:13:19:18,0:01:27,78,51
10139,139 bottles of beer on the wall,Option 1,0.6525219277,09APR1960,01JAN1960:05:43:49,0:00:21,63,6
10140,140 bottles of beer on the wall,Option 1,0.4684071925,29MAY1961,01JAN1960:02:53:36,0:00:46,68,4
10141,141 bottles of beer on the wall,Option 1,0.8581724013,16MAY1960,01JAN1960:01:45:44,0:01:32,31,85
10142,142 bottles of beer on the wall,Option 1,0.825792401,23APR1961,01JAN1960:12:03:13,0:00:49,36,45
10143,143 bottles of beer on the wall,Option 1,0.3172852538,20FEB1962,01JAN1960:12:38:31,0:01:34,51,78
10144,144 bottles of beer on the wall,Option 1,0.670397946,27JAN1962,01JAN1960:04:59:37,0:00:39,38,99
10145,145 bottles of beer on the wall,Option 1,0.3304372441,04JUN1960,01JAN1960:00:39:12,0:00:29,88,76
10146,146 bottles of beer on the wall,Option 1,0.845151971,31JUL1962,01JAN1960:05:03:34,0:00:13,2,80
10147,147 bottles of beer on the wall,Option 1,0.7957223709,02FEB1961,01JAN1960:00:03:07,0:01:11,29,99
10148,148 bottles of beer on the wall,Option 1,0.323337108,29FEB1960,01JAN1960:01:58:05,0:01:17,23,65
10149,149 bottles of beer on the wall,Option 1,0.1813316611,29JUN1960,01JAN1960:02:18:08,0:00:40,45,52
10150,150 bottles of beer on the wall,Option 1,0.7860426655,05MAR1962,01JAN1960:01:57:15,0:00:26,31,91
10151,151 bottles of beer on the wall,Option 1,0.3305453571,09APR1960,01JAN1960:07:08:32,0:01:30,72,15
10152,152 bottles of beer on the wall,Option 1,0.9367212513,18AUG1962,01JAN1960:10:36:03,0:01:26,85,81
10153,153 bottles of beer on the wall,Option 1,0.3385623458,19MAR1962,01JAN1960:04:21:46,0:01:29,11,54
10154,154 bottles of beer on the wall,Option 1,0.9756794413,17JUN1961,01JAN1960:08:35:40,0:00:34,3,72
10155,155 bottles of beer on the wall,Option 1,0.6385958868,21OCT1961,01JAN1960:08:51:00,0:00:50,1,6
10156,156 bottles of beer on the wall,Option 1,0.3569769959,14AUG1960,01JAN1960:10:57:16,0:00:05,5,94
10157,157 bottles of beer on the wall,Option 1,0.8559997239,23MAR1962,01JAN1960:12:03:38,0:00:08,96,68
10158,158 bottles of beer on the wall,Option 1,0.2293701918,13AUG1960,01JAN1960:06:36:47,0:00:07,87,87
10159,159 bottles of beer on the wall,Option 1,0.0007910165,20SEP1962,01JAN1960:11:49:02,0:00:55,18,69
10160,160 bottles of beer on the wall,Option 1,0.5876370373,08JAN1960,01JAN1960:00:59:15,0:01:26,27,36
10161,161 bottles of beer on the wall,Option 1,0.2354667514,11OCT1961,01JAN1960:01:27:14,0:01:04,90,28
10162,162 bottles of beer on the wall,Option 1,0.0144103263,11AUG1961,01JAN1960:02:37:41,0:01:39,92,8
10163,163 bottles of beer on the wall,Option 1,0.7087855668,03JUL1962,01JAN1960:02:07:23,0:01:35,51,33
10164,164 bottles of beer on the wall,Option 1,0.7251478106,20MAY1960,01JAN1960:12:15:23,0:01:28,58,7
10165,165 bottles of beer on the wall,Option 1,0.9629398403,06APR1962,01JAN1960:01:05:24,0:01:39,84,6
10166,166 bottles of beer on the wall,Option 1,0.5155049164,14OCT1960,01JAN1960:04:02:06,0:00:30,63,96
10167,167 bottles of beer on the wall,Option 1,0.1016342775,11MAY1960,01JAN1960:05:55:03,0:00:01,31,44
10168,168 bottles of beer on the wall,Option 1,0.3690353596,12NOV1961,01JAN1960:12:49:02,0:00:03,2,79
10169,169 bottles of beer on the wall,Option 1,0.5573803501,02SEP1962,01JAN1960:12:59:56,0:00:31,7,95
10170,170 bottles of beer on the wall,Option 1,0.2008119497,10JUN1961,01JAN1960:05:59:06,0:01:29,88,4
10171,171 bottles of beer on the wall,Option 1,0.6939068505,25MAY1962,01JAN1960:07:20:06,0:01:08,87,8
10172,172 bottles of beer on the wall,Option 1,0.7013406594,14JUL1960,01JAN1960:04:04:24,0:00:11,44,96
10173,173 bottles of beer on the wall,Option 1,0.83506724,30APR1961,01JAN1960:12:44:40,0:00:10,74,70
10174,174 bottles of beer on the wall,Option 1,0.9339991943,26JAN1962,01JAN1960:04:59:32,0:01:09,13,66
10175,175 bottles of beer on the wall,Option 1,0.8333402787,18FEB1961,01JAN1960:07:25:44,0:00:28,47,2
10176,176 bottles of beer on the wall,Option 1,0.5998844433,03MAR1962,01JAN1960:03:45:33,0:00:52,2,61
10177,177 bottles of beer on the wall,Option 1,0.6161394634,18DEC1960,01JAN1960:05:35:25,0:00:50,70,22
10178,178 bottles of beer on the wall,Option 1,0.0821002392,21APR1960,01JAN1960:10:08:56,0:01:40,28,9
10179,179 bottles of beer on the wall,Option 1,0.6845213462,23MAY1960,01JAN1960:13:15:46,0:00:03,89,13
10180,180 bottles of beer on the wall,Option 1,0.3839034477,14MAY1960,01JAN1960:03:22:17,0:01:11,15,38
10181,181 bottles of beer on the wall,Option 1,0.7949567609,21AUG1962,01JAN1960:02:41:01,0:00:57,90,93
10182,182 bottles of beer on the wall,Option 1,0.5079025419,23SEP1962,01JAN1960:02:22:31,0:01:07,83,32
10183,183 bottles of beer on the wall,Option 1,0.3215162574,26DEC1961,01JAN1960:09:03:00,0:01:38,46,94
10184,184 bottles of beer on the wall,Option 1,0.3322958058,12MAY1961,01JAN1960:02:48:05,0:00:46,80,54
10185,185 bottles of beer on the wall,Option 1,0.6510801453,07SEP1960,01JAN1960:11:49:02,0:00:59,51,47
10186,186 bottles of beer on the wall,Option 1,0.060995535,15AUG1960,01JAN1960:02:21:08,0:01:40,5,61
10187,187 bottles of beer on the wall,Option 1,0.8541180551,14SEP1960,01JAN1960:13:29:33,0:01:23,17,14
10188,188 bottles of beer on the wall,Option 1,0.9427926219,23JUL1960,01JAN1960:05:19:05,0:01:13,22,97
10189,189 bottles of beer on the wall,Option 1,0.2325015186,01FEB1960,01JAN1960:11:50:07,0:01:22,6,53
10190,190 bottles of beer on the wall,Option 1,0.3687101493,21FEB1962,01JAN1960:06:44:23,0:00:13,16,30
10191,191 bottles of beer on the wall,Option 1,0.7647511232,09JAN1960,01JAN1960:13:06:29,0:01:35,6,97
10192,192 bottles of beer on the wall,Option 1,0.4105463565,17AUG1961,01JAN1960:11:04:32,0:01:14,38,33
10193,193 bottles of beer on the wall,Option 1,0.8785403831,12JUL1962,01JAN1960:04:11:05,0:00:29,19,82
10194,194 bottles of beer on the wall,Option 1,0.9304303433,11JUL1961,01JAN1960:12:36:57,0:01:02,20,35
10195,195 bottles of beer on the wall,Option 1,0.7302505256,01MAR1961,01JAN1960:01:38:35,0:00:42,16,35
10196,196 bottles of beer on the wall,Option 1,0.2536906177,04SEP1962,01JAN1960:05:18:23,0:01:18,91,50
10197,197 bottles of beer on the wall,Option 1,0.1181504503,08AUG1961,01JAN1960:09:27:54,0:01:26,20,13
10198,198 bottles of beer on the wall,Option 1,0.9275614228,17JUL1961,01JAN1960:01:52:18,0:00:06,52,73
10199,199 bottles of beer on the wall,Option 1,0.7495222128,04APR1961,01JAN1960:09:28:04,0:00:42,30,41
10200,200 bottles of beer on the wall,Option 1,0.925741082,02FEB1962,01JAN1960:12:23:10,0:00:07,79,17
10201,201 bottles of beer on the wall,Option 1,0.2591843359,04DEC1960,01JAN1960:12:46:41,0:00:00,53,58
10202,202 bottles of beer on the wall,Option 1,0.4289995704,17NOV1961,01JAN1960:02:20:52,0:00:35,41,25
10203,203 bottles of beer on the wall,Option 1,0.4625803807,24JAN1960,01JAN1960:08:20:44,0:01:11,84,66
10204,204 bottles of beer on the wall,Option 1,0.858440102,31AUG1962,01JAN1960:08:51:40,0:00:12,18,51
10205,205 bottles of beer on the wall,Option 1,0.8964499016,01SEP1962,01JAN1960:05:33:47,0:00:23,34,77
10206,206 bottles of beer on the wall,Option 1,0.5742789063,24OCT1961,01JAN1960:02:31:04,0:01:08,27,66
10207,207 bottles of beer on the wall,Option 1,0.4864150954,29SEP1960,01JAN1960:09:27:46,0:01:28,31,26
10208,208 bottles of beer on the wall,Option 1,0.4511992249,04DEC1960,01JAN1960:09:39:26,0:00:42,49,98
10209,209 bottles of beer on the wall,Option 1,0.4218624157,13SEP1961,01JAN1960:01:40:55,0:01:39,35,50
10210,210 bottles of beer on the wall,Option 1,0.1572868331,15FEB1960,01JAN1960:07:01:15,0:00:51,43,1
10211,211 bottles of beer on the wall,Option 1,0.713915177,23MAR1960,01JAN1960:11:08:53,0:00:15,18,61
10212,212 bottles of beer on the wall,Option 1,0.5677882165,19MAY1960,01JAN1960:01:27:23,0:01:02,34,89
10213,213 bottles of beer on the wall,Option 1,0.7552938581,12SEP1961,01JAN1960:11:47:33,0:00:38,44,46
10214,214 bottles of beer on the wall,Option 1,0.6071256071,28DEC1961,01JAN1960:05:28:18,0:01:23,84,66
10215,215 bottles of beer on the wall,Option 1,0.7717189266,12MAR1960,01JAN1960:01:21:26,0:01:00,28,22
10216,216 bottles of beer on the wall,Option 1,0.8985594329,24MAR1961,01JAN1960:10:48:58,0:01:31,93,2
10217,217 bottles of beer on the wall,Option 1,0.3156879904,13AUG1960,01JAN1960:07:10:46,0:01:18,100,54
10218,218 bottles of beer on the wall,Option 1,0.3408455315,08JUN1961,01JAN1960:02:26:49,0:00:05,65,82
10219,219 bottles of beer on the wall,Option 1,0.6263580553,08JUN1962,01JAN1960:05:59:46,0:01:03,76,88
10220,220 bottles of beer on the wall,Option 1,0.2878925355,19DEC1961,01JAN1960:08:23:41,0:00:00,92,1
10221,221 bottles of beer on the wall,Option 1,0.0901017348,19JUL1962,01JAN1960:09:50:47,0:00:43,21,84
10222,222 bottles of beer on the wall,Option 1,0.8967759362,14SEP1960,01JAN1960:12:25:58,0:01:22,34,50
10223,223 bottles of beer on the wall,Option 1,0.9878171943,03DEC1961,01JAN1960:03:43:09,0:00:17,11,84
10224,224 bottles of beer on the wall,Option 1,0.5275036886,13DEC1961,01JAN1960:03:12:56,0:01:36,85,49
10225,225 bottles of beer on the wall,Option 1,0.442012436,12JUN1960,01JAN1960:11:40:23,0:01:40,76,87
10226,226 bottles of beer on the wall,Option 1,0.582103689,10FEB1961,01JAN1960:01:50:49,0:00:59,53,29
10227,227 bottles of beer on the wall,Option 1,0.5757669842,01NOV1960,01JAN1960:13:47:33,0:00:43,55,6
10228,228 bottles of beer on the wall,Option 1,0.4786617507,07JAN1960,01JAN1960:13:36:24,0:01:22,91,53
10229,229 bottles of beer on the wall,Option 1,0.1386274957,06APR1962,01JAN1960:03:48:29,0:01:27,36,48
10230,230 bottles of beer on the wall,Option 1,0.4188394893,31MAY1962,01JAN1960:10:30:51,0:00:54,5,87
10231,231 bottles of beer on the wall,Option 1,0.9250617777,18OCT1960,01JAN1960:04:29:52,0:00:38,34,94
10232,232 bottles of beer on the wall,Option 1,0.3077528124,05FEB1960,01JAN1960:09:37:42,0:01:13,58,75
10233,233 bottles of beer on the wall,Option 1,0.7316332277,29NOV1960,01JAN1960:08:56:57,0:01:13,34,53
10234,234 bottles of beer on the wall,Option 1,0.5666298352,21NOV1960,01JAN1960:07:51:09,0:01:08,97,71
10235,235 bottles of beer on the wall,Option 1,0.5736639409,03JUL1962,01JAN1960:11:57:25,0:00:51,15,49
10236,236 bottles of beer on the wall,Option 1,0.6785667616,11FEB1962,01JAN1960:09:47:20,0:00:50,65,21
10237,237 bottles of beer on the wall,Option 1,0.3721726869,05JUL1962,01JAN1960:11:58:22,0:01:32,82,21
10238,238 bottles of beer on the wall,Option 1,0.0332283876,17AUG1961,01JAN1960:13:11:34,0:00:54,83,30
10239,239 bottles of beer on the wall,Option 1,0.9734656848,02JAN1961,01JAN1960:00:36:43,0:00:19,31,54
10240,240 bottles of beer on the wall,Option 1,0.3022106021,16FEB1961,01JAN1960:13:50:38,0:00:40,22,66
10241,241 bottles of beer on the wall,Option 1,0.7546903294,06JUL1961,01JAN1960:12:36:17,0:01:29,16,85
10242,242 bottles of beer on the wall,Option 1,0.2509871834,07MAR1962,01JAN1960:10:38:28,0:00:39,7,8
10243,243 bottles of beer on the wall,Option 1,0.9526996668,15JAN1960,01JAN1960:04:24:42,0:01:01,69,80
10244,244 bottles of beer on the wall,Option 1,0.1816610122,06FEB1962,01JAN1960:08:46:51,0:00:54,89,91
10245,245 bottles of beer on the wall,Option 1,0.3928658876,21JUL1962,01JAN1960:12:59:42,0:00:38,24,27
10246,246 bottles of beer on the wall,Option 1,0.3774878524,18FEB1961,01JAN1960:07:40:49,0:01:31,88,93
10247,247 bottles of beer on the wall,Option 1,0.6063659362,01NOV1960,01JAN1960:01:19:07,0:00:05,82,73
10248,248 bottles of beer on the wall,Option 1,0.119603098,14JUN1960,01JAN1960:04:29:22,0:00:58,87,47
10249,249 bottles of beer on the wall,Option 1,0.4833748445,03JUL1960,01JAN1960:01:53:54,0:00:37,34,33
10250,250 bottles of beer on the wall,Option 1,0.2244539946,10AUG1961,01JAN1960:06:19:01,0:01:15,87,97
10251,251 bottles of beer on the wall,Option 1,0.9368193191,11JUN1962,01JAN1960:06:37:14,0:00:46,94,39
10252,252 bottles of beer on the wall,Option 1,0.1791427751,10NOV1961,01JAN1960:00:49:22,0:00:47,96,21
10253,253 bottles of beer on the wall,Option 1,0.5836302874,06JUN1961,01JAN1960:08:39:34,0:01:01,78,49
10254,254 bottles of beer on the wall,Option 1,0.1289398275,28DEC1960,01JAN1960:12:25:05,0:00:43,67,99
10255,255 bottles of beer on the wall,Option 1,0.7833669785,05SEP1962,01JAN1960:02:47:35,0:00:20,25,2
10256,256 bottles of beer on the wall,Option 1,0.4945342483,29JAN1960,01JAN1960:00:54:13,0:01:13,72,56
10257,257 bottles of beer on the wall,Option 1,0.0635836129,05JAN1961,01JAN1960:08:10:04,0:00:52,11,10
10258,258 bottles of beer on the wall,Option 1,0.8188241654,09FEB1962,01JAN1960:06:33:00,0:01:21,41,96
10259,259 bottles of beer on the wall,Option 1,0.3398916076,11FEB1960,01JAN1960:07:12:29,0:00:56,18,76
10260,260 bottles of beer on the wall,Option 1,0.0814064155,21MAY1961,01JAN1960:11:03:51,0:01:18,78,29
10261,261 bottles of beer on the wall,Option 1,0.6653245542,20JAN1962,01JAN1960:08:03:31,0:00:18,39,95
10262,262 bottles of beer on the wall,Option 1,0.4036777021,04AUG1962,01JAN1960:12:32:27,0:00:08,57,63
10263,263 bottles of beer on the wall,Option 1,0.8931138603,07JAN1962,01JAN1960:09:04:24,0:00:32,6,27
10264,264 bottles of beer on the wall,Option 1,0.528584433,06APR1962,01JAN1960:09:43:19,0:01:00,24,41
10265,265 bottles of beer on the wall,Option 1,0.8267822945,29JUL1960,01JAN1960:00:48:11,0:00:01,81,78
10266,266 bottles of beer on the wall,Option 1,0.7218411401,17FEB1960,01JAN1960:07:30:38,0:00:08,35,81
10267,267 bottles of beer on the wall,Option 1,0.1475262773,11NOV1960,01JAN1960:13:44:20,0:00:57,36,68
10268,268 bottles of beer on the wall,Option 1,0.9412727286,30DEC1960,01JAN1960:02:46:30,0:01:19,5,92
10269,269 bottles of beer on the wall,Option 1,0.3038877548,27NOV1960,01JAN1960:10:50:10,0:01:21,43,95
10270,270 bottles of beer on the wall,Option 1,0.2756435532,15APR1962,01JAN1960:09:05:28,0:01:34,11,14
10271,271 bottles of beer on the wall,Option 1,0.7056001121,31AUG1960,01JAN1960:08:48:52,0:00:02,9,51
10272,272 bottles of beer on the wall,Option 1,0.5273708508,21SEP1962,01JAN1960:12:58:13,0:00:28,97,69
10273,273 bottles of beer on the wall,Option 1,0.6002807215,03MAY1960,01JAN1960:10:14:48,0:00:40,52,32
10274,274 bottles of beer on the wall,Option 1,0.6100557971,20JUN1960,01JAN1960:08:11:55,0:00:27,90,14
10275,275 bottles of beer on the wall,Option 1,0.4197408638,07JUN1961,01JAN1960:12:07:18,0:00:26,64,100
10276,276 bottles of beer on the wall,Option 1,0.4903712498,19JAN1960,01JAN1960:01:06:26,0:00:03,35,24
10277,277 bottles of beer on the wall,Option 1,0.6658435406,04NOV1960,01JAN1960:00:04:17,0:00:37,7,84
10278,278 bottles of beer on the wall,Option 1,0.5491365942,14JAN1961,01JAN1960:04:12:49,0:00:27,99,47
10279,279 bottles of beer on the wall,Option 1,0.4473488622,13MAY1961,01JAN1960:12:06:34,0:01:16,19,20
10280,280 bottles of beer on the wall,Option 1,0.4511988663,06JUL1962,01JAN1960:10:05:51,0:00:56,76,34
10281,281 bottles of beer on the wall,Option 1,0.0783031066,11JUN1961,01JAN1960:09:58:43,0:01:05,9,63
10282,282 bottles of beer on the wall,Option 1,0.776985302,20JUL1962,01JAN1960:10:44:29,0:01:00,59,10
10283,283 bottles of beer on the wall,Option 1,0.468099362,31AUG1962,01JAN1960:05:26:33,0:00:20,35,52
10284,284 bottles of beer on the wall,Option 1,0.4040679696,20FEB1962,01JAN1960:06:27:25,0:00:04,76,30
10285,285 bottles of beer on the wall,Option 1,0.4549995947,20FEB1962,01JAN1960:10:36:57,0:00:34,2,43
10286,286 bottles of beer on the wall,Option 1,0.7455339361,16SEP1961,01JAN1960:08:39:35,0:01:00,42,44
10287,287 bottles of beer on the wall,Option 1,0.0209561712,04JAN1960,01JAN1960:05:52:58,0:00:24,32,7
10288,288 bottles of beer on the wall,Option 1,0.4955981842,04JAN1962,01JAN1960:02:56:03,0:00:30,85,31
10289,289 bottles of beer on the wall,Option 1,0.4131368219,10FEB1960,01JAN1960:11:57:31,0:00:16,37,88
10290,290 bottles of beer on the wall,Option 1,0.3282186721,17OCT1960,01JAN1960:10:54:04,0:00:56,72,28
10291,291 bottles of beer on the wall,Option 1,0.2116929005,18JAN1962,01JAN1960:06:56:27,0:00:11,87,82
10292,292 bottles of beer on the wall,Option 1,0.8483731937,12FEB1962,01JAN1960:05:05:41,0:01:36,12,83
10293,293 bottles of beer on the wall,Option 1,0.1560111345,13NOV1960,01JAN1960:10:04:22,0:00:03,94,4
10294,294 bottles of beer on the wall,Option 1,0.7046207808,12APR1962,01JAN1960:13:50:47,0:00:32,31,97
10295,295 bottles of beer on the wall,Option 1,0.2716620403,04AUG1961,01JAN1960:01:52:29,0:00:57,99,44
10296,296 bottles of beer on the wall,Option 1,0.5543203496,12SEP1960,01JAN1960:13:43:54,0:00:44,49,1
10297,297 bottles of beer on the wall,Option 1,0.983109036,31JUL1962,01JAN1960:01:07:33,0:00:36,4,10
10298,298 bottles of beer on the wall,Option 1,0.8123072115,14SEP1962,01JAN1960:06:16:12,0:01:25,88,96
10299,299 bottles of beer on the wall,Option 1,0.4276896559,05OCT1960,01JAN1960:02:55:07,0:00:58,83,76
10300,300 bottles of beer on the wall,Option 1,0.8921809042,19JAN1962,01JAN1960:02:05:38,0:00:12,80,13
10301,301 bottles of beer on the wall,Option 1,0.6041374279,10DEC1961,01JAN1960:01:06:29,0:01:27,62,9
10302,302 bottles of beer on the wall,Option 1,0.0460550185,31MAY1962,01JAN1960:03:03:56,0:00:05,33,88
10303,303 bottles of beer on the wall,Option 1,0.1868385622,12APR1962,01JAN1960:12:42:44,0:01:05,65,18
10304,304 bottles of beer on the wall,Option 1,0.3386632657,28SEP1961,01JAN1960:11:24:06,0:00:42,2,93
10305,305 bottles of beer on the wall,Option 1,0.6400271019,01JUN1960,01JAN1960:13:33:07,0:01:30,60,72
10306,306 bottles of beer on the wall,Option 1,0.9534907304,18NOV1961,01JAN1960:02:02:51,0:00:54,7,57
10307,307 bottles of beer on the wall,Option 1,0.6663103745,06SEP1961,01JAN1960:05:36:49,0:00:43,88,2
10308,308 bottles of beer on the wall,Option 1,0.5392553073,13FEB1962,01JAN1960:11:28:18,0:01:08,16,8
10309,309 bottles of beer on the wall,Option 1,0.0747909025,17OCT1961,01JAN1960:08:36:12,0:00:41,49,42
10310,310 bottles of beer on the wall,Option 1,0.3249381847,30SEP1960,01JAN1960:08:12:54,0:00:09,96,89
10311,311 bottles of beer on the wall,Option 1,0.9231011951,19MAY1962,01JAN1960:05:10:33,0:00:50,30,9
10312,312 bottles of beer on the wall,Option 1,0.4658221637,21MAY1961,01JAN1960:12:55:25,0:01:39,16,20
10313,313 bottles of beer on the wall,Option 1,0.7215524673,21FEB1960,01JAN1960:02:00:07,0:01:40,95,94
10314,314 bottles of beer on the wall,Option 1,0.7328679942,28OCT1961,01JAN1960:09:07:00,0:00:25,42,71
10315,315 bottles of beer on the wall,Option 1,0.1276036776,12JUN1960,01JAN1960:01:54:08,0:00:56,57,42
10316,316 bottles of beer on the wall,Option 1,0.1270824723,15SEP1960,01JAN1960:03:19:25,0:00:21,85,9
10317,317 bottles of beer on the wall,Option 1,0.3750520117,13JUN1961,01JAN1960:04:33:09,0:01:15,24,20
10318,318 bottles of beer on the wall,Option 1,0.5777822102,10DEC1960,01JAN1960:13:32:14,0:00:09,98,28
10319,319 bottles of beer on the wall,Option 1,0.140476402,27AUG1962,01JAN1960:08:52:46,0:01:08,64,83
10320,320 bottles of beer on the wall,Option 1,0.2589205551,31MAY1961,01JAN1960:08:33:06,0:00:53,28,98
10321,321 bottles of beer on the wall,Option 1,0.7350722825,16SEP1962,01JAN1960:05:47:44,0:01:17,79,95
10322,322 bottles of beer on the wall,Option 1,0.1476364542,15JAN1960,01JAN1960:12:21:20,0:00:20,86,62
10323,323 bottles of beer on the wall,Option 1,0.8700561099,15MAY1962,01JAN1960:00:47:05,0:00:20,90,15
10324,324 bottles of beer on the wall,Option 1,0.6408788802,12SEP1962,01JAN1960:11:50:31,0:00:53,41,72
10325,325 bottles of beer on the wall,Option 1,0.6961101623,27NOV1960,01JAN1960:00:10:49,0:01:17,28,72
10326,326 bottles of beer on the wall,Option 1,0.1467710059,24FEB1961,01JAN1960:01:13:38,0:00:33,14,5
10327,327 bottles of beer on the wall,Option 1,0.0215573572,09JUN1961,01JAN1960:11:47:17,0:00:21,57,10
10328,328 bottles of beer on the wall,Option 1,0.4173900054,25JUL1962,01JAN1960:12:28:20,0:00:23,73,90
10329,329 bottles of beer on the wall,Option 1,0.6395625713,02NOV1961,01JAN1960:08:49:34,0:00:37,77,79
10330,330 bottles of beer on the wall,Option 1,0.0091438908,18MAY1962,01JAN1960:05:10:05,0:00:41,15,31
10331,331 bottles of beer on the wall,Option 1,0.1024675197,11DEC1960,01JAN1960:13:12:57,0:00:23,50,13
10332,332 bottles of beer on the wall,Option 1,0.057470562,11MAY1961,01JAN1960:03:43:04,0:00:17,48,14
10333,333 bottles of beer on the wall,Option 1,0.8478633872,21JUL1961,01JAN1960:03:45:42,0:01:31,22,40
10334,334 bottles of beer on the wall,Option 1,0.3442252541,24JUN1960,01JAN1960:01:19:31,0:00:48,82,25
10335,335 bottles of beer on the wall,Option 1,0.7338460184,06JUN1962,01JAN1960:03:32:34,0:01:04,6,31
10336,336 bottles of beer on the wall,Option 1,0.6217917342,09MAR1961,01JAN1960:06:37:39,0:00:50,70,84
10337,337 bottles of beer on the wall,Option 1,0.6684890807,10OCT1961,01JAN1960:05:34:24,0:01:20,66,18
10338,338 bottles of beer on the wall,Option 1,0.3695247562,05SEP1962,01JAN1960:00:25:21,0:01:18,48,37
10339,339 bottles of beer on the wall,Option 1,0.9429265987,06DEC1960,01JAN1960:07:11:17,0:00:38,59,1
10340,340 bottles of beer on the wall,Option 1,0.9266307265,17JUL1960,01JAN1960:06:33:59,0:00:21,12,13
10341,341 bottles of beer on the wall,Option 1,0.7280535543,23FEB1961,01JAN1960:05:01:10,0:00:34,73,25
10342,342 bottles of beer on the wall,Option 1,0.488654495,15AUG1962,01JAN1960:01:24:33,0:00:56,59,25
10343,343 bottles of beer on the wall,Option 1,0.9526806548,28DEC1960,01JAN1960:07:26:17,0:00:58,97,61
10344,344 bottles of beer on the wall,Option 1,0.526025336,14JAN1960,01JAN1960:10:02:08,0:00:55,11,77
10345,345 bottles of beer on the wall,Option 1,0.807215352,03JUL1961,01JAN1960:12:49:47,0:00:01,40,7
10346,346 bottles of beer on the wall,Option 1,0.9305162979,28FEB1960,01JAN1960:09:46:40,0:00:59,56,28
10347,347 bottles of beer on the wall,Option 1,0.7591318552,18FEB1962,01JAN1960:13:25:32,0:01:10,41,9
10348,348 bottles of beer on the wall,Option 1,0.4177664911,11SEP1961,01JAN1960:09:55:17,0:01:39,76,82
10349,349 bottles of beer on the wall,Option 1,0.4690050443,05DEC1961,01JAN1960:11:05:15,0:01:09,63,40
10350,350 bottles of beer on the wall,Option 1,0.7541399979,31AUG1961,01JAN1960:12:30:45,0:00:33,57,12
10351,351 bottles of beer on the wall,Option 1,0.1392844325,17MAR1962,01JAN1960:08:20:38,0:00:41,85,45
10352,352 bottles of beer on the wall,Option 1,0.1020530235,23DEC1961,01JAN1960:09:46:20,0:00:01,55,56
10353,353 bottles of beer on the wall,Option 1,0.0257998794,04DEC1961,01JAN1960:09:47:10,0:00:31,100,2
10354,354 bottles of beer on the wall,Option 1,0.1238113316,20MAR1962,01JAN1960:09:15:30,0:00:01,74,11
10355,355 bottles of beer on the wall,Option 1,0.4214245292,24NOV1960,01JAN1960:04:24:09,0:01:01,79,83
10356,356 bottles of beer on the wall,Option 1,0.3243381057,12FEB1961,01JAN1960:00:55:59,0:00:50,30,52
10357,357 bottles of beer on the wall,Option 1,0.9735697345,24NOV1960,01JAN1960:07:10:56,0:01:33,64,2
10358,358 bottles of beer on the wall,Option 1,0.4796259461,28JAN1961,01JAN1960:11:51:29,0:01:03,19,29
10359,359 bottles of beer on the wall,Option 1,0.003359966,01SEP1960,01JAN1960:13:24:25,0:00:09,66,60
10360,360 bottles of beer on the wall,Option 1,0.5773700334,21JAN1960,01JAN1960:10:15:32,0:00:40,9,21
10361,361 bottles of beer on the wall,Option 1,0.0792848342,25JAN1962,01JAN1960:06:00:35,0:01:25,73,73
10362,362 bottles of beer on the wall,Option 1,0.9339359365,30MAY1961,01JAN1960:09:08:13,0:00:56,12,56
10363,363 bottles of beer on the wall,Option 1,0.3517632132,12FEB1961,01JAN1960:12:07:19,0:00:01,74,69
10364,364 bottles of beer on the wall,Option 1,0.4088954895,17MAR1961,01JAN1960:08:04:51,0:01:01,70,66
10365,365 bottles of beer on the wall,Option 1,0.1254259623,30DEC1961,01JAN1960:06:47:12,0:00:01,79,43
10366,366 bottles of beer on the wall,Option 1,0.9190132958,28MAY1961,01JAN1960:06:35:42,0:00:07,19,31
10367,367 bottles of beer on the wall,Option 1,0.3033860015,17MAY1962,01JAN1960:05:32:03,0:00:32,57,73
10368,368 bottles of beer on the wall,Option 1,0.1463442846,02SEP1962,01JAN1960:01:24:29,0:00:53,19,64
10369,369 bottles of beer on the wall,Option 1,0.5516236343,18JUN1962,01JAN1960:10:52:23,0:00:11,51,40
10370,370 bottles of beer on the wall,Option 1,0.5205378246,19JAN1960,01JAN1960:06:54:14,0:00:58,2,72
10371,371 bottles of beer on the wall,Option 1,0.9941610768,28MAR1962,01JAN1960:04:55:58,0:00:22,46,65
10372,372 bottles of beer on the wall,Option 1,0.065678,07MAY1961,01JAN1960:10:17:35,0:00:10,54,100
10373,373 bottles of beer on the wall,Option 1,0.7222646138,17JUL1961,01JAN1960:01:47:32,0:00:51,26,96
10374,374 bottles of beer on the wall,Option 1,0.8772228294,23JUL1960,01JAN1960:00:30:51,0:00:40,18,45
10375,375 bottles of beer on the wall,Option 1,0.3651081847,11DEC1961,01JAN1960:00:46:15,0:00:15,14,90
10376,376 bottles of beer on the wall,Option 1,0.3800431529,15AUG1960,01JAN1960:05:30:55,0:00:19,13,74
10377,377 bottles of beer on the wall,Option 1,0.1077003503,26FEB1960,01JAN1960:04:48:40,0:00:08,51,53
10378,378 bottles of beer on the wall,Option 1,0.7945664035,06MAR1961,01JAN1960:05:36:47,0:00:45,65,39
10379,379 bottles of beer on the wall,Option 1,0.8754883054,06JUN1960,01JAN1960:06:09:33,0:00:04,3,3
10380,380 bottles of beer on the wall,Option 1,0.9975561108,10AUG1960,01JAN1960:10:34:33,0:00:28,92,29
10381,381 bottles of beer on the wall,Option 1,0.9817031599,07JUL1960,01JAN1960:01:40:00,0:00:39,63,45
10382,382 bottles of beer on the wall,Option 1,0.4427802341,07JAN1962,01JAN1960:01:21:32,0:01:31,7,54
10383,383 bottles of beer on the wall,Option 1,0.03180474,17JUL1962,01JAN1960:07:15:54,0:01:08,72,60
10384,384 bottles of beer on the wall,Option 1,0.1031627707,10MAY1962,01JAN1960:02:52:58,0:01:31,6,64
10385,385 bottles of beer on the wall,Option 1,0.911744344,01MAY1960,01JAN1960:03:51:16,0:01:04,1,54
10386,386 bottles of beer on the wall,Option 1,0.4912374353,13FEB1961,01JAN1960:07:22:49,0:01:21,70,71
10387,387 bottles of beer on the wall,Option 1,0.8803869509,04JUL1960,01JAN1960:12:14:05,0:00:18,78,88
10388,388 bottles of beer on the wall,Option 1,0.0596609544,17DEC1960,01JAN1960:08:29:20,0:00:53,13,84
10389,389 bottles of beer on the wall,Option 1,0.6625022132,12JAN1961,01JAN1960:11:15:39,0:01:05,10,31
10390,390 bottles of beer on the wall,Option 1,0.2669677358,05OCT1961,01JAN1960:00:48:03,0:01:33,29,31
10391,391 bottles of beer on the wall,Option 1,0.8095563454,04DEC1961,01JAN1960:07:54:13,0:01:15,95,2
10392,392 bottles of beer on the wall,Option 1,0.6406704796,27JAN1961,01JAN1960:03:35:55,0:00:36,92,47
10393,393 bottles of beer on the wall,Option 1,0.2188341847,02MAR1960,01JAN1960:04:05:21,0:00:11,28,34
10394,394 bottles of beer on the wall,Option 1,0.7052043424,09JUN1962,01JAN1960:07:00:21,0:01:14,84,19
10395,395 bottles of beer on the wall,Option 1,0.9843204464,18APR1960,01JAN1960:04:54:31,0:01:29,46,46
10396,396 bottles of beer on the wall,Option 1,0.329249541,10SEP1961,01JAN1960:13:21:04,0:00:21,70,11
10397,397 bottles of beer on the wall,Option 1,0.2073628675,13JUL1962,01JAN1960:11:16:26,0:01:23,17,97
10398,398 bottles of beer on the wall,Option 1,0.7881676665,29JUN1962,01JAN1960:11:36:47,0:00:50,39,72
10399,399 bottles of beer on the wall,Option 1,0.4347905537,31AUG1962,01JAN1960:02:30:30,0:00:21,86,61
10400,400 bottles of beer on the wall,Option 1,0.2937454084,05APR1962,01JAN1960:02:44:06,0:00:32,27,81
10401,401 bottles of beer on the wall,Option 1,0.6659902565,10APR1961,01JAN1960:11:53:59,0:00:01,80,17
10402,402 bottles of beer on the wall,Option 1,0.7637229686,07APR1962,01JAN1960:05:45:25,0:01:28,11,17
10403,403 bottles of beer on the wall,Option 1,0.3325480941,19MAR1961,01JAN1960:09:57:05,0:00:27,9,99
10404,404 bottles of beer on the wall,Option 1,0.580015553,10AUG1960,01JAN1960:06:15:44,0:00:25,27,99
10405,405 bottles of beer on the wall,Option 1,0.2514696071,08APR1961,01JAN1960:10:37:45,0:00:17,29,59
10406,406 bottles of beer on the wall,Option 1,0.3792107284,19MAR1962,01JAN1960:04:49:30,0:00:07,44,38
10407,407 bottles of beer on the wall,Option 1,0.4702913125,13DEC1961,01JAN1960:09:03:31,0:00:38,95,90
10408,408 bottles of beer on the wall,Option 1,0.4207190659,03FEB1961,01JAN1960:00:37:47,0:00:38,37,65
10409,409 bottles of beer on the wall,Option 1,0.2485069117,08DEC1961,01JAN1960:07:18:28,0:01:39,91,64
10410,410 bottles of beer on the wall,Option 1,0.3257893502,27NOV1961,01JAN1960:11:33:02,0:00:54,41,7
10411,411 bottles of beer on the wall,Option 1,0.0967283533,11AUG1962,01JAN1960:07:23:15,0:00:21,90,1
10412,412 bottles of beer on the wall,Option 1,0.532676542,01SEP1960,01JAN1960:02:46:29,0:00:45,31,48
10413,413 bottles of beer on the wall,Option 1,0.2564602151,15JAN1961,01JAN1960:01:09:11,0:01:21,16,89
10414,414 bottles of beer on the wall,Option 1,0.0865634024,20MAR1962,01JAN1960:12:56:45,0:00:05,75,51
10415,415 bottles of beer on the wall,Option 1,0.2926342321,07FEB1960,01JAN1960:06:48:55,0:00:36,66,33
10416,416 bottles of beer on the wall,Option 1,0.0678594029,06OCT1961,01JAN1960:07:14:58,0:01:26,50,16
10417,417 bottles of beer on the wall,Option 1,0.6376664767,09JUN1960,01JAN1960:05:00:13,0:01:37,7,92
10418,418 bottles of beer on the wall,Option 1,0.4795483525,14JUN1962,01JAN1960:00:00:50,0:00:50,33,74
10419,419 bottles of beer on the wall,Option 1,0.3492934342,22MAR1960,01JAN1960:08:54:52,0:01:26,61,72
10420,420 bottles of beer on the wall,Option 1,0.5085071356,14MAR1960,01JAN1960:09:47:51,0:00:56,36,63
10421,421 bottles of beer on the wall,Option 1,0.414953564,25MAR1961,01JAN1960:03:35:19,0:00:30,47,30
10422,422 bottles of beer on the wall,Option 1,0.2431976652,25SEP1960,01JAN1960:08:47:25,0:00:17,6,42
10423,423 bottles of beer on the wall,Option 1,0.2370444998,04MAR1962,01JAN1960:00:16:44,0:01:36,54,100
10424,424 bottles of beer on the wall,Option 1,0.8687893324,12OCT1961,01JAN1960:03:16:33,0:00:56,97,25
10425,425 bottles of beer on the wall,Option 1,0.0470510335,10MAY1960,01JAN1960:02:44:07,0:01:05,83,59
10426,426 bottles of beer on the wall,Option 1,0.7114342887,12APR1960,01JAN1960:02:17:40,0:00:39,57,97
10427,427 bottles of beer on the wall,Option 1,0.6176668283,05JUL1962,01JAN1960:09:09:12,0:01:03,92,38
10428,428 bottles of beer on the wall,Option 1,0.0657907743,01JUL1962,01JAN1960:11:03:37,0:01:35,97,63
10429,429 bottles of beer on the wall,Option 1,0.280104912,13MAR1962,01JAN1960:10:35:08,0:01:07,42,35
10430,430 bottles of beer on the wall,Option 1,0.3639827088,02APR1960,01JAN1960:12:00:50,0:00:40,91,84
10431,431 bottles of beer on the wall,Option 1,0.2130561137,25AUG1961,01JAN1960:12:07:22,0:01:37,70,9
10432,432 bottles of beer on the wall,Option 1,0.9656705889,23DEC1960,01JAN1960:02:36:48,0:01:28,23,92
10433,433 bottles of beer on the wall,Option 1,0.5824601052,22JAN1961,01JAN1960:01:19:48,0:00:32,73,6
10434,434 bottles of beer on the wall,Option 1,0.5207124942,23APR1961,01JAN1960:10:45:16,0:01:08,45,85
10435,435 bottles of beer on the wall,Option 1,0.9280530661,01NOV1960,01JAN1960:12:46:59,0:01:36,57,4
10436,436 bottles of beer on the wall,Option 1,0.8982810149,29NOV1961,01JAN1960:09:23:13,0:01:15,100,68
10437,437 bottles of beer on the wall,Option 1,0.3268259467,04MAR1960,01JAN1960:01:22:42,0:00:04,99,61
10438,438 bottles of beer on the wall,Option 1,0.2038002704,12FEB1962,01JAN1960:09:03:24,0:00:40,97,78
10439,439 bottles of beer on the wall,Option 1,0.0798850833,11MAY1960,01JAN1960:00:32:50,0:00:37,7,49
10440,440 bottles of beer on the wall,Option 1,0.6697000566,01SEP1960,01JAN1960:08:04:03,0:00:30,7,68
10441,441 bottles of beer on the wall,Option 1,0.550699767,11JAN1960,01JAN1960:06:33:15,0:01:09,19,10
10442,442 bottles of beer on the wall,Option 1,0.9514032798,07FEB1962,01JAN1960:06:03:16,0:01:13,65,87
10443,443 bottles of beer on the wall,Option 1,0.1182718324,08FEB1960,01JAN1960:11:28:52,0:00:46,61,59
10444,444 bottles of beer on the wall,Option 1,0.5772118874,11FEB1962,01JAN1960:01:14:29,0:01:07,16,22
10445,445 bottles of beer on the wall,Option 1,0.9828714463,06DEC1960,01JAN1960:05:47:08,0:01:40,66,4
10446,446 bottles of beer on the wall,Option 1,0.1229167269,02JUN1960,01JAN1960:09:43:51,0:01:34,29,24
10447,447 bottles of beer on the wall,Option 1,0.2102257522,09MAR1961,01JAN1960:04:06:09,0:01:27,53,78
10448,448 bottles of beer on the wall,Option 1,0.9958884935,20FEB1962,01JAN1960:06:43:53,0:00:07,42,65
10449,449 bottles of beer on the wall,Option 1,0.3530408085,04MAY1961,01JAN1960:11:26:59,0:01:37,76,35
10450,450 bottles of beer on the wall,Option 1,0.2848354258,03SEP1960,01JAN1960:13:26:36,0:00:25,69,38
10451,451 bottles of beer on the wall,Option 1,0.1461860818,10JUN1960,01JAN1960:01:24:25,0:00:02,61,23
10452,452 bottles of beer on the wall,Option 1,0.2033735766,29AUG1960,01JAN1960:12:30:17,0:00:19,32,75
10453,453 bottles of beer on the wall,Option 1,0.7973149958,26JUN1961,01JAN1960:04:46:06,0:00:21,94,14
10454,454 bottles of beer on the wall,Option 1,0.6812086425,07NOV1961,01JAN1960:01:59:51,0:00:12,89,59
10455,455 bottles of beer on the wall,Option 1,0.6111464974,24FEB1962,01JAN1960:07:42:56,0:00:15,23,92
10456,456 bottles of beer on the wall,Option 1,0.9542484209,09APR1961,01JAN1960:09:09:17,0:01:26,87,93
10457,457 bottles of beer on the wall,Option 1,0.9818577077,18AUG1960,01JAN1960:12:24:47,0:01:08,18,20
10458,458 bottles of beer on the wall,Option 1,0.9331120881,06JUL1961,01JAN1960:10:10:02,0:01:40,78,36
10459,459 bottles of beer on the wall,Option 1,0.8953045587,22APR1960,01JAN1960:04:47:34,0:00:37,13,46
10460,460 bottles of beer on the wall,Option 1,0.1584420461,08JAN1961,01JAN1960:07:47:49,0:00:05,85,61
10461,461 bottles of beer on the wall,Option 1,0.9324573814,24DEC1960,01JAN1960:02:13:36,0:00:22,55,94
10462,462 bottles of beer on the wall,Option 1,0.0813189871,21AUG1961,01JAN1960:09:18:28,0:00:36,42,49
10463,463 bottles of beer on the wall,Option 1,0.8736312594,17MAY1962,01JAN1960:12:52:58,0:00:30,45,7
10464,464 bottles of beer on the wall,Option 1,0.1894013794,06NOV1960,01JAN1960:12:56:13,0:01:30,11,50
10465,465 bottles of beer on the wall,Option 1,0.9149773772,07JUN1960,01JAN1960:08:53:28,0:00:22,23,17
10466,466 bottles of beer on the wall,Option 1,0.6329479598,27JUN1962,01JAN1960:07:38:23,0:00:06,68,14
10467,467 bottles of beer on the wall,Option 1,0.1897066413,21AUG1961,01JAN1960:10:15:28,0:01:12,59,46
10468,468 bottles of beer on the wall,Option 1,0.8352205767,16MAR1961,01JAN1960:06:48:50,0:00:44,60,37
10469,469 bottles of beer on the wall,Option 1,0.3339443432,09OCT1960,01JAN1960:00:52:53,0:00:27,70,44
10470,470 bottles of beer on the wall,Option 1,0.1096137567,09JUL1962,01JAN1960:08:28:10,0:01:15,88,81
10471,471 bottles of beer on the wall,Option 1,0.1481936733,10JAN1962,01JAN1960:06:38:41,0:00:56,21,77
10472,472 bottles of beer on the wall,Option 1,0.5630390432,01MAR1960,01JAN1960:06:35:09,0:01:08,70,32
10473,473 bottles of beer on the wall,Option 1,0.0604085713,12APR1962,01JAN1960:02:41:26,0:00:46,36,17
10474,474 bottles of beer on the wall,Option 1,0.6011423606,25DEC1961,01JAN1960:02:57:45,0:01:11,36,18
10475,475 bottles of beer on the wall,Option 1,0.7698335782,31JUL1962,01JAN1960:07:46:29,0:01:34,72,17
10476,476 bottles of beer on the wall,Option 1,0.3823641224,17MAR1962,01JAN1960:03:34:37,0:00:09,27,86
10477,477 bottles of beer on the wall,Option 1,0.9225378446,12JAN1962,01JAN1960:08:41:25,0:01:06,45,20
10478,478 bottles of beer on the wall,Option 1,0.2979750453,23JUN1962,01JAN1960:10:06:36,0:01:28,88,7
10479,479 bottles of beer on the wall,Option 1,0.4988665942,15JUL1961,01JAN1960:02:33:06,0:01:33,85,1
10480,480 bottles of beer on the wall,Option 1,0.5243853585,29JUL1960,01JAN1960:00:26:18,0:00:31,48,77
10481,481 bottles of beer on the wall,Option 1,0.6049248826,12JUL1962,01JAN1960:10:01:41,0:00:16,66,45
10482,482 bottles of beer on the wall,Option 1,0.6312438024,01OCT1961,01JAN1960:05:18:12,0:00:04,43,27
10483,483 bottles of beer on the wall,Option 1,0.3366865974,17MAY1962,01JAN1960:01:44:17,0:00:01,31,25
10484,484 bottles of beer on the wall,Option 1,0.0813266188,08AUG1962,01JAN1960:06:18:27,0:00:08,71,63
10485,485 bottles of beer on the wall,Option 1,0.3601163455,23JAN1962,01JAN1960:11:26:01,0:00:37,41,88
10486,486 bottles of beer on the wall,Option 1,0.9033777345,13AUG1961,01JAN1960:00:16:14,0:00:56,82,33
10487,487 bottles of beer on the wall,Option 1,0.1716986667,23DEC1960,01JAN1960:12:06:34,0:01:13,2,32
10488,488 bottles of beer on the wall,Option 1,0.9734818912,11SEP1961,01JAN1960:00:34:41,0:00:28,17,7
10489,489 bottles of beer on the wall,Option 1,0.0618140223,17DEC1961,01JAN1960:06:26:30,0:00:38,94,40
10490,490 bottles of beer on the wall,Option 1,0.0204490144,22AUG1960,01JAN1960:01:50:18,0:00:19,40,56
10491,491 bottles of beer on the wall,Option 1,0.8719323929,23MAY1960,01JAN1960:12:36:06,0:00:08,49,44
10492,492 bottles of beer on the wall,Option 1,0.2656292181,28JUN1962,01JAN1960:05:32:50,0:01:35,15,39
10493,493 bottles of beer on the wall,Option 1,0.37794835,23JUL1962,01JAN1960:13:15:43,0:00:56,6,86
10494,494 bottles of beer on the wall,Option 1,0.6395865733,17JAN1961,01JAN1960:12:20:12,0:01:31,22,87
10495,495 bottles of beer on the wall,Option 1,0.4408595098,05JUL1960,01JAN1960:12:21:53,0:01:40,25,27
10496,496 bottles of beer on the wall,Option 1,0.4846261169,02DEC1961,01JAN1960:12:41:08,0:00:06,7,63
10497,497 bottles of beer on the wall,Option 1,0.7903671478,14MAY1962,01JAN1960:05:09:21,0:01:03,98,25
10498,498 bottles of beer on the wall,Option 1,0.60474184,13OCT1961,01JAN1960:03:52:59,0:01:22,98,98
10499,499 bottles of beer on the wall,Option 1,0.1213259218,23APR1962,01JAN1960:06:29:47,0:01:35,38,70
10500,500 bottles of beer on the wall,Option 1,0.7882370487,17FEB1962,01JAN1960:02:00:25,0:00:12,1,74
1 PRIMARY_KEY_FIELD SOME_CHAR SOME_DROPDOWN SOME_NUM SOME_DATE SOME_DATETIME SOME_TIME SOME_SHORTNUM SOME_BESTNUM
2 0 abc Option abc 42 12FEB1960 01JAN1960:00:00:42 0:00:42 3 44
3 1 more dummy data Option 2 42 12FEB1960 01JAN1960:00:00:42 0:07:02 3 44
4 2 even more dummy data Option 3 42 12FEB1960 01JAN1960:00:00:42 0:02:22 3 44
5 3 It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: It was a dark and stormy night. The wind was blowing a gale! The captain said to his mate - mate, tell us a tale. And this, is the tale he told: Option 2 1613.001 27FEB1961 01JAN1960:00:07:03 0:00:44 3 44
6 4 if you can fill the unforgiving minute Option 1 1613.0011235 02AUG1971 29MAY1973:06:12:03 0:06:52 3 44
7 1010 10 bottles of beer on the wall Option 1 0.9153696885 04MAR1962 01JAN1960:12:47:55 0:01:40 92 76
8 1011 11 bottles of beer on the wall Option 1 0.3531217558 29MAR1960 01JAN1960:03:33:24 0:01:03 80 29
9 1012 12 bottles of beer on the wall Option 1 0.6743748717 02AUG1962 01JAN1960:07:25:59 0:00:10 16 98
10 1013 13 bottles of beer on the wall Option 1 0.1305445992 11SEP1960 01JAN1960:13:51:32 0:00:35 73 15
11 1014 14 bottles of beer on the wall Option 1 0.7409067949 26JUL1960 01JAN1960:05:18:10 0:00:41 30 89
12 1015 15 bottles of beer on the wall Option 1 0.0869016028 28FEB1961 01JAN1960:13:23:45 0:00:44 80 3
13 1016 16 bottles of beer on the wall Option 1 0.0462121419 09AUG1962 01JAN1960:07:42:38 0:01:17 62 2
14 1017 17 bottles of beer on the wall Option 1 0.7501918947 14MAY1962 01JAN1960:04:40:20 0:00:15 53 65
15 1018 18 bottles of beer on the wall Option 1 0.7300173294 03AUG1962 01JAN1960:03:20:41 0:00:41 21 60
16 1019 19 bottles of beer on the wall Option 1 0.6960950437 01JUN1960 01JAN1960:01:58:52 0:01:08 38 5
17 1020 20 bottles of beer on the wall Option 1 0.6190566065 30MAY1961 01JAN1960:09:04:20 0:01:07 92 23
18 1021 21 bottles of beer on the wall Option 1 0.5173368238 07JAN1961 01JAN1960:07:52:34 0:00:52 57 21
19 1022 22 bottles of beer on the wall Option 1 0.4720626452 07NOV1960 01JAN1960:12:12:00 0:00:26 53 32
20 1023 23 bottles of beer on the wall Option 1 0.2856596393 08AUG1960 01JAN1960:06:09:25 0:00:28 40 12
21 1024 24 bottles of beer on the wall Option 1 0.5160869418 02JUN1960 01JAN1960:06:36:06 0:01:10 41 81
22 1025 25 bottles of beer on the wall Option 1 0.1683158517 05JAN1961 01JAN1960:08:14:35 0:00:06 18 53
23 1026 26 bottles of beer on the wall Option 1 0.8951142248 28NOV1961 01JAN1960:03:31:17 0:00:58 79 54
24 1027 27 bottles of beer on the wall Option 1 0.7037817481 01SEP1961 01JAN1960:05:48:34 0:00:29 50 15
25 1028 28 bottles of beer on the wall Option 1 0.6193826714 31MAR1962 01JAN1960:02:49:39 0:00:24 78 87
26 1029 29 bottles of beer on the wall Option 1 0.9339028457 06DEC1961 01JAN1960:02:57:57 0:00:24 73 64
27 1030 30 bottles of beer on the wall Option 1 0.5647351339 10AUG1960 01JAN1960:11:02:59 0:00:55 39 28
28 1031 31 bottles of beer on the wall Option 1 0.1218988607 19JUN1961 01JAN1960:04:19:32 0:00:58 51 32
29 1032 32 bottles of beer on the wall Option 1 0.3459929113 14MAY1962 01JAN1960:05:42:48 0:00:54 96 46
30 1033 33 bottles of beer on the wall Option 1 0.092664999 31AUG1962 01JAN1960:00:08:34 0:00:51 69 90
31 1034 34 bottles of beer on the wall Option 1 0.9793458097 08FEB1960 01JAN1960:01:55:23 0:00:42 45 28
32 1035 35 bottles of beer on the wall Option 1 0.8964386624 18DEC1961 01JAN1960:04:42:45 0:00:07 49 97
33 1036 36 bottles of beer on the wall Option 1 0.0961652911 13NOV1960 01JAN1960:03:44:53 0:01:25 62 59
34 1037 37 bottles of beer on the wall Option 1 0.3475089201 16JAN1962 01JAN1960:01:35:19 0:00:15 23 50
35 1038 38 bottles of beer on the wall Option 1 0.3096271312 21MAY1960 01JAN1960:09:51:33 0:00:15 2 71
36 1039 39 bottles of beer on the wall Option 1 0.9445223114 28AUG1962 01JAN1960:07:09:31 0:00:12 30 31
37 1040 40 bottles of beer on the wall Option 1 0.5626084667 06NOV1960 01JAN1960:01:42:16 0:01:14 18 97
38 1041 41 bottles of beer on the wall Option 1 0.9432962513 01JUN1962 01JAN1960:03:30:04 0:00:11 20 34
39 1042 42 bottles of beer on the wall Option 1 0.5802429382 08JUL1961 01JAN1960:08:12:43 0:01:26 18 5
40 1043 43 bottles of beer on the wall Option 1 0.1970176255 27MAR1961 01JAN1960:00:19:45 0:01:29 13 76
41 1044 44 bottles of beer on the wall Option 1 0.4980671608 05JAN1961 01JAN1960:13:36:08 0:00:56 4 36
42 1045 45 bottles of beer on the wall Option 1 0.2486515531 05MAY1962 01JAN1960:08:47:09 0:00:42 2 23
43 1046 46 bottles of beer on the wall Option 1 0.4097825794 20JUN1960 01JAN1960:03:33:26 0:00:31 98 71
44 1047 47 bottles of beer on the wall Option 1 0.138754441 28JAN1960 01JAN1960:00:57:41 0:00:18 80 32
45 1048 48 bottles of beer on the wall Option 1 0.0249874415 03MAR1960 01JAN1960:11:33:53 0:00:04 96 76
46 1049 49 bottles of beer on the wall Option 1 0.8395310011 06NOV1961 01JAN1960:09:54:04 0:00:52 28 45
47 1050 50 bottles of beer on the wall Option 1 0.0942291618 14APR1962 01JAN1960:08:09:30 0:01:36 37 86
48 1051 51 bottles of beer on the wall Option 1 0.1670458001 13NOV1961 01JAN1960:01:05:55 0:00:25 42 83
49 1052 52 bottles of beer on the wall Option 1 0.3122402715 04JUN1960 01JAN1960:03:47:47 0:01:01 18 78
50 1053 53 bottles of beer on the wall Option 1 0.3854694261 14JUN1960 01JAN1960:02:43:08 0:00:06 22 67
51 1054 54 bottles of beer on the wall Option 1 0.1950434345 14NOV1961 01JAN1960:02:46:34 0:00:55 42 0
52 1055 55 bottles of beer on the wall Option 1 0.4948673586 29MAR1962 01JAN1960:00:48:06 0:01:04 28 4
53 1056 56 bottles of beer on the wall Option 1 0.6464513832 06SEP1962 01JAN1960:10:08:36 0:01:02 43 82
54 1057 57 bottles of beer on the wall Option 1 0.0724864798 20JUN1961 01JAN1960:12:22:51 0:01:27 82 53
55 1058 58 bottles of beer on the wall Option 1 0.8114467793 20MAR1962 01JAN1960:06:11:33 0:01:29 40 89
56 1059 59 bottles of beer on the wall Option 1 0.6348024321 28JUN1962 01JAN1960:05:21:21 0:01:37 55 41
57 1060 60 bottles of beer on the wall Option 1 0.8019492933 08APR1961 01JAN1960:12:37:00 0:01:29 49 88
58 1061 61 bottles of beer on the wall Option 1 0.4695742002 29JAN1962 01JAN1960:08:54:24 0:00:15 40 91
59 1062 62 bottles of beer on the wall Option 1 0.902706475 15JUN1961 01JAN1960:09:46:49 0:00:23 74 70
60 1063 63 bottles of beer on the wall Option 1 0.4557614594 16JUL1961 01JAN1960:02:06:05 0:01:09 7 3
61 1064 64 bottles of beer on the wall Option 1 0.6632444466 20MAY1961 01JAN1960:02:44:44 0:00:20 42 100
62 1065 65 bottles of beer on the wall Option 1 0.3901674 31AUG1961 01JAN1960:07:56:49 0:00:32 98 3
63 1066 66 bottles of beer on the wall Option 1 0.8453234848 30JUN1962 01JAN1960:04:51:54 0:01:02 51 22
64 1067 67 bottles of beer on the wall Option 1 0.9370150906 26APR1960 01JAN1960:04:05:08 0:01:39 28 86
65 1068 68 bottles of beer on the wall Option 1 0.8854161277 22MAR1962 01JAN1960:10:38:49 0:01:07 60 85
66 1069 69 bottles of beer on the wall Option 1 0.1327841906 24MAY1960 01JAN1960:01:18:46 0:01:15 88 85
67 1070 70 bottles of beer on the wall Option 1 0.5846563226 27JUL1962 01JAN1960:03:52:31 0:00:09 20 8
68 1071 71 bottles of beer on the wall Option 1 0.0257193684 18FEB1961 01JAN1960:03:25:01 0:00:29 1 62
69 1072 72 bottles of beer on the wall Option 1 0.9471486034 01JUN1962 01JAN1960:04:05:25 0:01:22 65 20
70 1073 73 bottles of beer on the wall Option 1 0.3037446282 16MAY1962 01JAN1960:05:10:19 0:00:01 14 34
71 1074 74 bottles of beer on the wall Option 1 0.2508690675 01NOV1961 01JAN1960:11:26:03 0:00:15 8 74
72 1075 75 bottles of beer on the wall Option 1 0.814380363 17SEP1960 01JAN1960:09:00:38 0:00:25 95 1
73 1076 76 bottles of beer on the wall Option 1 0.3761493621 16AUG1961 01JAN1960:01:48:17 0:00:52 5 38
74 1077 77 bottles of beer on the wall Option 1 0.3621215761 25JUL1961 01JAN1960:11:48:47 0:01:20 86 90
75 1078 78 bottles of beer on the wall Option 1 0.0268799584 20MAY1961 01JAN1960:12:43:34 0:01:00 70 96
76 1079 79 bottles of beer on the wall Option 1 0.4112483945 27JUL1962 01JAN1960:01:20:24 0:01:26 66 20
77 1080 80 bottles of beer on the wall Option 1 0.9501868011 15APR1961 01JAN1960:09:58:20 0:00:51 93 79
78 1081 81 bottles of beer on the wall Option 1 0.9866548018 13SEP1961 01JAN1960:05:20:04 0:00:14 28 97
79 1082 82 bottles of beer on the wall Option 1 0.9907830073 22FEB1962 01JAN1960:03:29:03 0:00:17 16 91
80 1083 83 bottles of beer on the wall Option 1 0.8927816567 11MAR1960 01JAN1960:05:52:48 0:01:26 54 14
81 1084 84 bottles of beer on the wall Option 1 0.12871663 02FEB1961 01JAN1960:10:34:37 0:00:44 52 90
82 1085 85 bottles of beer on the wall Option 1 0.5490252802 02JAN1960 01JAN1960:06:11:58 0:00:27 4 98
83 1086 86 bottles of beer on the wall Option 1 0.5432773864 11FEB1960 01JAN1960:08:40:00 0:01:15 79 19
84 1087 87 bottles of beer on the wall Option 1 0.8223943137 01OCT1960 01JAN1960:08:11:33 0:01:19 2 86
85 1088 88 bottles of beer on the wall Option 1 0.8496777699 09FEB1962 01JAN1960:03:10:35 0:00:15 95 6
86 1089 89 bottles of beer on the wall Option 1 0.9308730536 27MAY1962 01JAN1960:11:57:53 0:01:18 86 90
87 1090 90 bottles of beer on the wall Option 1 0.3072653344 23FEB1962 01JAN1960:04:52:38 0:00:25 85 17
88 1091 91 bottles of beer on the wall Option 1 0.7687679575 12FEB1960 01JAN1960:08:47:11 0:01:20 8 7
89 1092 92 bottles of beer on the wall Option 1 0.1873595105 29SEP1961 01JAN1960:04:29:58 0:00:29 17 78
90 1093 93 bottles of beer on the wall Option 1 0.0495966631 03OCT1961 01JAN1960:03:18:50 0:00:39 89 56
91 1094 94 bottles of beer on the wall Option 1 0.2607690526 19SEP1960 01JAN1960:03:22:28 0:00:29 81 16
92 1095 95 bottles of beer on the wall Option 1 0.549640266 07JUN1962 01JAN1960:06:15:32 0:00:04 57 70
93 1096 96 bottles of beer on the wall Option 1 0.9993291092 08MAR1961 01JAN1960:13:49:08 0:00:33 37 28
94 1097 97 bottles of beer on the wall Option 1 0.9517237963 02SEP1960 01JAN1960:05:16:03 0:00:40 77 61
95 1098 98 bottles of beer on the wall Option 1 0.5952155588 14FEB1962 01JAN1960:05:05:11 0:01:29 63 83
96 1099 99 bottles of beer on the wall Option 1 0.7526210732 05MAY1961 01JAN1960:06:58:36 0:00:02 95 1
97 10100 100 bottles of beer on the wall Option 1 0.307558153 17MAY1961 01JAN1960:06:13:01 0:01:37 68 7
98 10101 101 bottles of beer on the wall Option 1 0.6596710829 15APR1962 01JAN1960:08:34:02 0:00:43 66 43
99 10102 102 bottles of beer on the wall Option 1 0.0202811998 31AUG1961 01JAN1960:07:22:35 0:01:31 57 35
100 10103 103 bottles of beer on the wall Option 1 0.6699061034 02MAY1962 01JAN1960:05:13:17 0:00:36 30 23
101 10104 104 bottles of beer on the wall Option 1 0.330972748 04JUN1961 01JAN1960:06:47:20 0:01:05 69 82
102 10105 105 bottles of beer on the wall Option 1 0.2274839176 25JAN1961 01JAN1960:05:34:51 0:00:56 63 68
103 10106 106 bottles of beer on the wall Option 1 0.5612243989 27JUN1962 01JAN1960:04:32:03 0:01:15 19 73
104 10107 107 bottles of beer on the wall Option 1 0.7398902111 03SEP1962 01JAN1960:08:34:07 0:00:17 90 6
105 10108 108 bottles of beer on the wall Option 1 0.6124899791 08AUG1960 01JAN1960:04:59:34 0:00:25 56 12
106 10109 109 bottles of beer on the wall Option 1 0.882404773 26JAN1961 01JAN1960:01:29:15 0:01:26 36 4
107 10110 110 bottles of beer on the wall Option 1 0.4427004733 27FEB1961 01JAN1960:06:16:49 0:01:40 97 84
108 10111 111 bottles of beer on the wall Option 1 0.3609524622 10JAN1962 01JAN1960:09:48:37 0:01:11 87 62
109 10112 112 bottles of beer on the wall Option 1 0.9408929562 03AUG1960 01JAN1960:06:54:26 0:00:08 19 33
110 10113 113 bottles of beer on the wall Option 1 0.3149107319 10AUG1962 01JAN1960:13:01:00 0:00:04 75 60
111 10114 114 bottles of beer on the wall Option 1 0.0525069181 17APR1962 01JAN1960:13:00:52 0:00:35 9 23
112 10115 115 bottles of beer on the wall Option 1 0.145448105 14FEB1962 01JAN1960:04:06:08 0:00:26 45 91
113 10116 116 bottles of beer on the wall Option 1 0.2444279959 10OCT1961 01JAN1960:08:03:12 0:01:37 12 41
114 10117 117 bottles of beer on the wall Option 1 0.4619846043 30JUL1960 01JAN1960:09:40:16 0:00:50 2 88
115 10118 118 bottles of beer on the wall Option 1 0.0316203502 13JUL1961 01JAN1960:08:31:39 0:01:05 60 94
116 10119 119 bottles of beer on the wall Option 1 0.4738720574 13AUG1960 01JAN1960:01:31:05 0:01:17 43 79
117 10120 120 bottles of beer on the wall Option 1 0.8058761856 11JUN1960 01JAN1960:12:56:35 0:00:08 92 36
118 10121 121 bottles of beer on the wall Option 1 0.2955600979 08JUL1962 01JAN1960:06:09:22 0:00:03 94 80
119 10122 122 bottles of beer on the wall Option 1 0.0064115427 18SEP1962 01JAN1960:00:06:24 0:00:13 72 75
120 10123 123 bottles of beer on the wall Option 1 0.5678159327 21APR1960 01JAN1960:10:54:21 0:00:16 75 67
121 10124 124 bottles of beer on the wall Option 1 0.1431510994 10JAN1962 01JAN1960:01:57:00 0:00:12 48 31
122 10125 125 bottles of beer on the wall Option 1 0.3805634409 26JAN1962 01JAN1960:03:03:19 0:01:29 83 52
123 10126 126 bottles of beer on the wall Option 1 0.3833517993 26APR1960 01JAN1960:11:27:41 0:00:44 99 36
124 10127 127 bottles of beer on the wall Option 1 0.5669089111 04MAR1961 01JAN1960:05:36:22 0:01:18 43 27
125 10128 128 bottles of beer on the wall Option 1 0.1514211843 01NOV1960 01JAN1960:07:45:50 0:01:02 22 12
126 10129 129 bottles of beer on the wall Option 1 0.0446588583 05JAN1961 01JAN1960:02:13:55 0:00:42 27 46
127 10130 130 bottles of beer on the wall Option 1 0.7892141611 22APR1962 01JAN1960:04:17:54 0:01:05 75 84
128 10131 131 bottles of beer on the wall Option 1 0.5012088001 24DEC1960 01JAN1960:13:03:23 0:01:22 87 82
129 10132 132 bottles of beer on the wall Option 1 0.2327582944 07APR1961 01JAN1960:01:33:15 0:01:14 18 46
130 10133 133 bottles of beer on the wall Option 1 0.2234651173 20MAR1961 01JAN1960:13:52:02 0:01:06 42 58
131 10134 134 bottles of beer on the wall Option 1 0.4954405918 10FEB1961 01JAN1960:13:51:14 0:01:36 35 11
132 10135 135 bottles of beer on the wall Option 1 0.7874922891 15AUG1960 01JAN1960:00:21:57 0:00:52 45 36
133 10136 136 bottles of beer on the wall Option 1 0.3992494891 06SEP1961 01JAN1960:09:51:46 0:01:25 26 9
134 10137 137 bottles of beer on the wall Option 1 0.3964866136 25MAY1960 01JAN1960:03:19:48 0:00:28 44 3
135 10138 138 bottles of beer on the wall Option 1 0.9466173323 06APR1962 01JAN1960:13:19:18 0:01:27 78 51
136 10139 139 bottles of beer on the wall Option 1 0.6525219277 09APR1960 01JAN1960:05:43:49 0:00:21 63 6
137 10140 140 bottles of beer on the wall Option 1 0.4684071925 29MAY1961 01JAN1960:02:53:36 0:00:46 68 4
138 10141 141 bottles of beer on the wall Option 1 0.8581724013 16MAY1960 01JAN1960:01:45:44 0:01:32 31 85
139 10142 142 bottles of beer on the wall Option 1 0.825792401 23APR1961 01JAN1960:12:03:13 0:00:49 36 45
140 10143 143 bottles of beer on the wall Option 1 0.3172852538 20FEB1962 01JAN1960:12:38:31 0:01:34 51 78
141 10144 144 bottles of beer on the wall Option 1 0.670397946 27JAN1962 01JAN1960:04:59:37 0:00:39 38 99
142 10145 145 bottles of beer on the wall Option 1 0.3304372441 04JUN1960 01JAN1960:00:39:12 0:00:29 88 76
143 10146 146 bottles of beer on the wall Option 1 0.845151971 31JUL1962 01JAN1960:05:03:34 0:00:13 2 80
144 10147 147 bottles of beer on the wall Option 1 0.7957223709 02FEB1961 01JAN1960:00:03:07 0:01:11 29 99
145 10148 148 bottles of beer on the wall Option 1 0.323337108 29FEB1960 01JAN1960:01:58:05 0:01:17 23 65
146 10149 149 bottles of beer on the wall Option 1 0.1813316611 29JUN1960 01JAN1960:02:18:08 0:00:40 45 52
147 10150 150 bottles of beer on the wall Option 1 0.7860426655 05MAR1962 01JAN1960:01:57:15 0:00:26 31 91
148 10151 151 bottles of beer on the wall Option 1 0.3305453571 09APR1960 01JAN1960:07:08:32 0:01:30 72 15
149 10152 152 bottles of beer on the wall Option 1 0.9367212513 18AUG1962 01JAN1960:10:36:03 0:01:26 85 81
150 10153 153 bottles of beer on the wall Option 1 0.3385623458 19MAR1962 01JAN1960:04:21:46 0:01:29 11 54
151 10154 154 bottles of beer on the wall Option 1 0.9756794413 17JUN1961 01JAN1960:08:35:40 0:00:34 3 72
152 10155 155 bottles of beer on the wall Option 1 0.6385958868 21OCT1961 01JAN1960:08:51:00 0:00:50 1 6
153 10156 156 bottles of beer on the wall Option 1 0.3569769959 14AUG1960 01JAN1960:10:57:16 0:00:05 5 94
154 10157 157 bottles of beer on the wall Option 1 0.8559997239 23MAR1962 01JAN1960:12:03:38 0:00:08 96 68
155 10158 158 bottles of beer on the wall Option 1 0.2293701918 13AUG1960 01JAN1960:06:36:47 0:00:07 87 87
156 10159 159 bottles of beer on the wall Option 1 0.0007910165 20SEP1962 01JAN1960:11:49:02 0:00:55 18 69
157 10160 160 bottles of beer on the wall Option 1 0.5876370373 08JAN1960 01JAN1960:00:59:15 0:01:26 27 36
158 10161 161 bottles of beer on the wall Option 1 0.2354667514 11OCT1961 01JAN1960:01:27:14 0:01:04 90 28
159 10162 162 bottles of beer on the wall Option 1 0.0144103263 11AUG1961 01JAN1960:02:37:41 0:01:39 92 8
160 10163 163 bottles of beer on the wall Option 1 0.7087855668 03JUL1962 01JAN1960:02:07:23 0:01:35 51 33
161 10164 164 bottles of beer on the wall Option 1 0.7251478106 20MAY1960 01JAN1960:12:15:23 0:01:28 58 7
162 10165 165 bottles of beer on the wall Option 1 0.9629398403 06APR1962 01JAN1960:01:05:24 0:01:39 84 6
163 10166 166 bottles of beer on the wall Option 1 0.5155049164 14OCT1960 01JAN1960:04:02:06 0:00:30 63 96
164 10167 167 bottles of beer on the wall Option 1 0.1016342775 11MAY1960 01JAN1960:05:55:03 0:00:01 31 44
165 10168 168 bottles of beer on the wall Option 1 0.3690353596 12NOV1961 01JAN1960:12:49:02 0:00:03 2 79
166 10169 169 bottles of beer on the wall Option 1 0.5573803501 02SEP1962 01JAN1960:12:59:56 0:00:31 7 95
167 10170 170 bottles of beer on the wall Option 1 0.2008119497 10JUN1961 01JAN1960:05:59:06 0:01:29 88 4
168 10171 171 bottles of beer on the wall Option 1 0.6939068505 25MAY1962 01JAN1960:07:20:06 0:01:08 87 8
169 10172 172 bottles of beer on the wall Option 1 0.7013406594 14JUL1960 01JAN1960:04:04:24 0:00:11 44 96
170 10173 173 bottles of beer on the wall Option 1 0.83506724 30APR1961 01JAN1960:12:44:40 0:00:10 74 70
171 10174 174 bottles of beer on the wall Option 1 0.9339991943 26JAN1962 01JAN1960:04:59:32 0:01:09 13 66
172 10175 175 bottles of beer on the wall Option 1 0.8333402787 18FEB1961 01JAN1960:07:25:44 0:00:28 47 2
173 10176 176 bottles of beer on the wall Option 1 0.5998844433 03MAR1962 01JAN1960:03:45:33 0:00:52 2 61
174 10177 177 bottles of beer on the wall Option 1 0.6161394634 18DEC1960 01JAN1960:05:35:25 0:00:50 70 22
175 10178 178 bottles of beer on the wall Option 1 0.0821002392 21APR1960 01JAN1960:10:08:56 0:01:40 28 9
176 10179 179 bottles of beer on the wall Option 1 0.6845213462 23MAY1960 01JAN1960:13:15:46 0:00:03 89 13
177 10180 180 bottles of beer on the wall Option 1 0.3839034477 14MAY1960 01JAN1960:03:22:17 0:01:11 15 38
178 10181 181 bottles of beer on the wall Option 1 0.7949567609 21AUG1962 01JAN1960:02:41:01 0:00:57 90 93
179 10182 182 bottles of beer on the wall Option 1 0.5079025419 23SEP1962 01JAN1960:02:22:31 0:01:07 83 32
180 10183 183 bottles of beer on the wall Option 1 0.3215162574 26DEC1961 01JAN1960:09:03:00 0:01:38 46 94
181 10184 184 bottles of beer on the wall Option 1 0.3322958058 12MAY1961 01JAN1960:02:48:05 0:00:46 80 54
182 10185 185 bottles of beer on the wall Option 1 0.6510801453 07SEP1960 01JAN1960:11:49:02 0:00:59 51 47
183 10186 186 bottles of beer on the wall Option 1 0.060995535 15AUG1960 01JAN1960:02:21:08 0:01:40 5 61
184 10187 187 bottles of beer on the wall Option 1 0.8541180551 14SEP1960 01JAN1960:13:29:33 0:01:23 17 14
185 10188 188 bottles of beer on the wall Option 1 0.9427926219 23JUL1960 01JAN1960:05:19:05 0:01:13 22 97
186 10189 189 bottles of beer on the wall Option 1 0.2325015186 01FEB1960 01JAN1960:11:50:07 0:01:22 6 53
187 10190 190 bottles of beer on the wall Option 1 0.3687101493 21FEB1962 01JAN1960:06:44:23 0:00:13 16 30
188 10191 191 bottles of beer on the wall Option 1 0.7647511232 09JAN1960 01JAN1960:13:06:29 0:01:35 6 97
189 10192 192 bottles of beer on the wall Option 1 0.4105463565 17AUG1961 01JAN1960:11:04:32 0:01:14 38 33
190 10193 193 bottles of beer on the wall Option 1 0.8785403831 12JUL1962 01JAN1960:04:11:05 0:00:29 19 82
191 10194 194 bottles of beer on the wall Option 1 0.9304303433 11JUL1961 01JAN1960:12:36:57 0:01:02 20 35
192 10195 195 bottles of beer on the wall Option 1 0.7302505256 01MAR1961 01JAN1960:01:38:35 0:00:42 16 35
193 10196 196 bottles of beer on the wall Option 1 0.2536906177 04SEP1962 01JAN1960:05:18:23 0:01:18 91 50
194 10197 197 bottles of beer on the wall Option 1 0.1181504503 08AUG1961 01JAN1960:09:27:54 0:01:26 20 13
195 10198 198 bottles of beer on the wall Option 1 0.9275614228 17JUL1961 01JAN1960:01:52:18 0:00:06 52 73
196 10199 199 bottles of beer on the wall Option 1 0.7495222128 04APR1961 01JAN1960:09:28:04 0:00:42 30 41
197 10200 200 bottles of beer on the wall Option 1 0.925741082 02FEB1962 01JAN1960:12:23:10 0:00:07 79 17
198 10201 201 bottles of beer on the wall Option 1 0.2591843359 04DEC1960 01JAN1960:12:46:41 0:00:00 53 58
199 10202 202 bottles of beer on the wall Option 1 0.4289995704 17NOV1961 01JAN1960:02:20:52 0:00:35 41 25
200 10203 203 bottles of beer on the wall Option 1 0.4625803807 24JAN1960 01JAN1960:08:20:44 0:01:11 84 66
201 10204 204 bottles of beer on the wall Option 1 0.858440102 31AUG1962 01JAN1960:08:51:40 0:00:12 18 51
202 10205 205 bottles of beer on the wall Option 1 0.8964499016 01SEP1962 01JAN1960:05:33:47 0:00:23 34 77
203 10206 206 bottles of beer on the wall Option 1 0.5742789063 24OCT1961 01JAN1960:02:31:04 0:01:08 27 66
204 10207 207 bottles of beer on the wall Option 1 0.4864150954 29SEP1960 01JAN1960:09:27:46 0:01:28 31 26
205 10208 208 bottles of beer on the wall Option 1 0.4511992249 04DEC1960 01JAN1960:09:39:26 0:00:42 49 98
206 10209 209 bottles of beer on the wall Option 1 0.4218624157 13SEP1961 01JAN1960:01:40:55 0:01:39 35 50
207 10210 210 bottles of beer on the wall Option 1 0.1572868331 15FEB1960 01JAN1960:07:01:15 0:00:51 43 1
208 10211 211 bottles of beer on the wall Option 1 0.713915177 23MAR1960 01JAN1960:11:08:53 0:00:15 18 61
209 10212 212 bottles of beer on the wall Option 1 0.5677882165 19MAY1960 01JAN1960:01:27:23 0:01:02 34 89
210 10213 213 bottles of beer on the wall Option 1 0.7552938581 12SEP1961 01JAN1960:11:47:33 0:00:38 44 46
211 10214 214 bottles of beer on the wall Option 1 0.6071256071 28DEC1961 01JAN1960:05:28:18 0:01:23 84 66
212 10215 215 bottles of beer on the wall Option 1 0.7717189266 12MAR1960 01JAN1960:01:21:26 0:01:00 28 22
213 10216 216 bottles of beer on the wall Option 1 0.8985594329 24MAR1961 01JAN1960:10:48:58 0:01:31 93 2
214 10217 217 bottles of beer on the wall Option 1 0.3156879904 13AUG1960 01JAN1960:07:10:46 0:01:18 100 54
215 10218 218 bottles of beer on the wall Option 1 0.3408455315 08JUN1961 01JAN1960:02:26:49 0:00:05 65 82
216 10219 219 bottles of beer on the wall Option 1 0.6263580553 08JUN1962 01JAN1960:05:59:46 0:01:03 76 88
217 10220 220 bottles of beer on the wall Option 1 0.2878925355 19DEC1961 01JAN1960:08:23:41 0:00:00 92 1
218 10221 221 bottles of beer on the wall Option 1 0.0901017348 19JUL1962 01JAN1960:09:50:47 0:00:43 21 84
219 10222 222 bottles of beer on the wall Option 1 0.8967759362 14SEP1960 01JAN1960:12:25:58 0:01:22 34 50
220 10223 223 bottles of beer on the wall Option 1 0.9878171943 03DEC1961 01JAN1960:03:43:09 0:00:17 11 84
221 10224 224 bottles of beer on the wall Option 1 0.5275036886 13DEC1961 01JAN1960:03:12:56 0:01:36 85 49
222 10225 225 bottles of beer on the wall Option 1 0.442012436 12JUN1960 01JAN1960:11:40:23 0:01:40 76 87
223 10226 226 bottles of beer on the wall Option 1 0.582103689 10FEB1961 01JAN1960:01:50:49 0:00:59 53 29
224 10227 227 bottles of beer on the wall Option 1 0.5757669842 01NOV1960 01JAN1960:13:47:33 0:00:43 55 6
225 10228 228 bottles of beer on the wall Option 1 0.4786617507 07JAN1960 01JAN1960:13:36:24 0:01:22 91 53
226 10229 229 bottles of beer on the wall Option 1 0.1386274957 06APR1962 01JAN1960:03:48:29 0:01:27 36 48
227 10230 230 bottles of beer on the wall Option 1 0.4188394893 31MAY1962 01JAN1960:10:30:51 0:00:54 5 87
228 10231 231 bottles of beer on the wall Option 1 0.9250617777 18OCT1960 01JAN1960:04:29:52 0:00:38 34 94
229 10232 232 bottles of beer on the wall Option 1 0.3077528124 05FEB1960 01JAN1960:09:37:42 0:01:13 58 75
230 10233 233 bottles of beer on the wall Option 1 0.7316332277 29NOV1960 01JAN1960:08:56:57 0:01:13 34 53
231 10234 234 bottles of beer on the wall Option 1 0.5666298352 21NOV1960 01JAN1960:07:51:09 0:01:08 97 71
232 10235 235 bottles of beer on the wall Option 1 0.5736639409 03JUL1962 01JAN1960:11:57:25 0:00:51 15 49
233 10236 236 bottles of beer on the wall Option 1 0.6785667616 11FEB1962 01JAN1960:09:47:20 0:00:50 65 21
234 10237 237 bottles of beer on the wall Option 1 0.3721726869 05JUL1962 01JAN1960:11:58:22 0:01:32 82 21
235 10238 238 bottles of beer on the wall Option 1 0.0332283876 17AUG1961 01JAN1960:13:11:34 0:00:54 83 30
236 10239 239 bottles of beer on the wall Option 1 0.9734656848 02JAN1961 01JAN1960:00:36:43 0:00:19 31 54
237 10240 240 bottles of beer on the wall Option 1 0.3022106021 16FEB1961 01JAN1960:13:50:38 0:00:40 22 66
238 10241 241 bottles of beer on the wall Option 1 0.7546903294 06JUL1961 01JAN1960:12:36:17 0:01:29 16 85
239 10242 242 bottles of beer on the wall Option 1 0.2509871834 07MAR1962 01JAN1960:10:38:28 0:00:39 7 8
240 10243 243 bottles of beer on the wall Option 1 0.9526996668 15JAN1960 01JAN1960:04:24:42 0:01:01 69 80
241 10244 244 bottles of beer on the wall Option 1 0.1816610122 06FEB1962 01JAN1960:08:46:51 0:00:54 89 91
242 10245 245 bottles of beer on the wall Option 1 0.3928658876 21JUL1962 01JAN1960:12:59:42 0:00:38 24 27
243 10246 246 bottles of beer on the wall Option 1 0.3774878524 18FEB1961 01JAN1960:07:40:49 0:01:31 88 93
244 10247 247 bottles of beer on the wall Option 1 0.6063659362 01NOV1960 01JAN1960:01:19:07 0:00:05 82 73
245 10248 248 bottles of beer on the wall Option 1 0.119603098 14JUN1960 01JAN1960:04:29:22 0:00:58 87 47
246 10249 249 bottles of beer on the wall Option 1 0.4833748445 03JUL1960 01JAN1960:01:53:54 0:00:37 34 33
247 10250 250 bottles of beer on the wall Option 1 0.2244539946 10AUG1961 01JAN1960:06:19:01 0:01:15 87 97
248 10251 251 bottles of beer on the wall Option 1 0.9368193191 11JUN1962 01JAN1960:06:37:14 0:00:46 94 39
249 10252 252 bottles of beer on the wall Option 1 0.1791427751 10NOV1961 01JAN1960:00:49:22 0:00:47 96 21
250 10253 253 bottles of beer on the wall Option 1 0.5836302874 06JUN1961 01JAN1960:08:39:34 0:01:01 78 49
251 10254 254 bottles of beer on the wall Option 1 0.1289398275 28DEC1960 01JAN1960:12:25:05 0:00:43 67 99
252 10255 255 bottles of beer on the wall Option 1 0.7833669785 05SEP1962 01JAN1960:02:47:35 0:00:20 25 2
253 10256 256 bottles of beer on the wall Option 1 0.4945342483 29JAN1960 01JAN1960:00:54:13 0:01:13 72 56
254 10257 257 bottles of beer on the wall Option 1 0.0635836129 05JAN1961 01JAN1960:08:10:04 0:00:52 11 10
255 10258 258 bottles of beer on the wall Option 1 0.8188241654 09FEB1962 01JAN1960:06:33:00 0:01:21 41 96
256 10259 259 bottles of beer on the wall Option 1 0.3398916076 11FEB1960 01JAN1960:07:12:29 0:00:56 18 76
257 10260 260 bottles of beer on the wall Option 1 0.0814064155 21MAY1961 01JAN1960:11:03:51 0:01:18 78 29
258 10261 261 bottles of beer on the wall Option 1 0.6653245542 20JAN1962 01JAN1960:08:03:31 0:00:18 39 95
259 10262 262 bottles of beer on the wall Option 1 0.4036777021 04AUG1962 01JAN1960:12:32:27 0:00:08 57 63
260 10263 263 bottles of beer on the wall Option 1 0.8931138603 07JAN1962 01JAN1960:09:04:24 0:00:32 6 27
261 10264 264 bottles of beer on the wall Option 1 0.528584433 06APR1962 01JAN1960:09:43:19 0:01:00 24 41
262 10265 265 bottles of beer on the wall Option 1 0.8267822945 29JUL1960 01JAN1960:00:48:11 0:00:01 81 78
263 10266 266 bottles of beer on the wall Option 1 0.7218411401 17FEB1960 01JAN1960:07:30:38 0:00:08 35 81
264 10267 267 bottles of beer on the wall Option 1 0.1475262773 11NOV1960 01JAN1960:13:44:20 0:00:57 36 68
265 10268 268 bottles of beer on the wall Option 1 0.9412727286 30DEC1960 01JAN1960:02:46:30 0:01:19 5 92
266 10269 269 bottles of beer on the wall Option 1 0.3038877548 27NOV1960 01JAN1960:10:50:10 0:01:21 43 95
267 10270 270 bottles of beer on the wall Option 1 0.2756435532 15APR1962 01JAN1960:09:05:28 0:01:34 11 14
268 10271 271 bottles of beer on the wall Option 1 0.7056001121 31AUG1960 01JAN1960:08:48:52 0:00:02 9 51
269 10272 272 bottles of beer on the wall Option 1 0.5273708508 21SEP1962 01JAN1960:12:58:13 0:00:28 97 69
270 10273 273 bottles of beer on the wall Option 1 0.6002807215 03MAY1960 01JAN1960:10:14:48 0:00:40 52 32
271 10274 274 bottles of beer on the wall Option 1 0.6100557971 20JUN1960 01JAN1960:08:11:55 0:00:27 90 14
272 10275 275 bottles of beer on the wall Option 1 0.4197408638 07JUN1961 01JAN1960:12:07:18 0:00:26 64 100
273 10276 276 bottles of beer on the wall Option 1 0.4903712498 19JAN1960 01JAN1960:01:06:26 0:00:03 35 24
274 10277 277 bottles of beer on the wall Option 1 0.6658435406 04NOV1960 01JAN1960:00:04:17 0:00:37 7 84
275 10278 278 bottles of beer on the wall Option 1 0.5491365942 14JAN1961 01JAN1960:04:12:49 0:00:27 99 47
276 10279 279 bottles of beer on the wall Option 1 0.4473488622 13MAY1961 01JAN1960:12:06:34 0:01:16 19 20
277 10280 280 bottles of beer on the wall Option 1 0.4511988663 06JUL1962 01JAN1960:10:05:51 0:00:56 76 34
278 10281 281 bottles of beer on the wall Option 1 0.0783031066 11JUN1961 01JAN1960:09:58:43 0:01:05 9 63
279 10282 282 bottles of beer on the wall Option 1 0.776985302 20JUL1962 01JAN1960:10:44:29 0:01:00 59 10
280 10283 283 bottles of beer on the wall Option 1 0.468099362 31AUG1962 01JAN1960:05:26:33 0:00:20 35 52
281 10284 284 bottles of beer on the wall Option 1 0.4040679696 20FEB1962 01JAN1960:06:27:25 0:00:04 76 30
282 10285 285 bottles of beer on the wall Option 1 0.4549995947 20FEB1962 01JAN1960:10:36:57 0:00:34 2 43
283 10286 286 bottles of beer on the wall Option 1 0.7455339361 16SEP1961 01JAN1960:08:39:35 0:01:00 42 44
284 10287 287 bottles of beer on the wall Option 1 0.0209561712 04JAN1960 01JAN1960:05:52:58 0:00:24 32 7
285 10288 288 bottles of beer on the wall Option 1 0.4955981842 04JAN1962 01JAN1960:02:56:03 0:00:30 85 31
286 10289 289 bottles of beer on the wall Option 1 0.4131368219 10FEB1960 01JAN1960:11:57:31 0:00:16 37 88
287 10290 290 bottles of beer on the wall Option 1 0.3282186721 17OCT1960 01JAN1960:10:54:04 0:00:56 72 28
288 10291 291 bottles of beer on the wall Option 1 0.2116929005 18JAN1962 01JAN1960:06:56:27 0:00:11 87 82
289 10292 292 bottles of beer on the wall Option 1 0.8483731937 12FEB1962 01JAN1960:05:05:41 0:01:36 12 83
290 10293 293 bottles of beer on the wall Option 1 0.1560111345 13NOV1960 01JAN1960:10:04:22 0:00:03 94 4
291 10294 294 bottles of beer on the wall Option 1 0.7046207808 12APR1962 01JAN1960:13:50:47 0:00:32 31 97
292 10295 295 bottles of beer on the wall Option 1 0.2716620403 04AUG1961 01JAN1960:01:52:29 0:00:57 99 44
293 10296 296 bottles of beer on the wall Option 1 0.5543203496 12SEP1960 01JAN1960:13:43:54 0:00:44 49 1
294 10297 297 bottles of beer on the wall Option 1 0.983109036 31JUL1962 01JAN1960:01:07:33 0:00:36 4 10
295 10298 298 bottles of beer on the wall Option 1 0.8123072115 14SEP1962 01JAN1960:06:16:12 0:01:25 88 96
296 10299 299 bottles of beer on the wall Option 1 0.4276896559 05OCT1960 01JAN1960:02:55:07 0:00:58 83 76
297 10300 300 bottles of beer on the wall Option 1 0.8921809042 19JAN1962 01JAN1960:02:05:38 0:00:12 80 13
298 10301 301 bottles of beer on the wall Option 1 0.6041374279 10DEC1961 01JAN1960:01:06:29 0:01:27 62 9
299 10302 302 bottles of beer on the wall Option 1 0.0460550185 31MAY1962 01JAN1960:03:03:56 0:00:05 33 88
300 10303 303 bottles of beer on the wall Option 1 0.1868385622 12APR1962 01JAN1960:12:42:44 0:01:05 65 18
301 10304 304 bottles of beer on the wall Option 1 0.3386632657 28SEP1961 01JAN1960:11:24:06 0:00:42 2 93
302 10305 305 bottles of beer on the wall Option 1 0.6400271019 01JUN1960 01JAN1960:13:33:07 0:01:30 60 72
303 10306 306 bottles of beer on the wall Option 1 0.9534907304 18NOV1961 01JAN1960:02:02:51 0:00:54 7 57
304 10307 307 bottles of beer on the wall Option 1 0.6663103745 06SEP1961 01JAN1960:05:36:49 0:00:43 88 2
305 10308 308 bottles of beer on the wall Option 1 0.5392553073 13FEB1962 01JAN1960:11:28:18 0:01:08 16 8
306 10309 309 bottles of beer on the wall Option 1 0.0747909025 17OCT1961 01JAN1960:08:36:12 0:00:41 49 42
307 10310 310 bottles of beer on the wall Option 1 0.3249381847 30SEP1960 01JAN1960:08:12:54 0:00:09 96 89
308 10311 311 bottles of beer on the wall Option 1 0.9231011951 19MAY1962 01JAN1960:05:10:33 0:00:50 30 9
309 10312 312 bottles of beer on the wall Option 1 0.4658221637 21MAY1961 01JAN1960:12:55:25 0:01:39 16 20
310 10313 313 bottles of beer on the wall Option 1 0.7215524673 21FEB1960 01JAN1960:02:00:07 0:01:40 95 94
311 10314 314 bottles of beer on the wall Option 1 0.7328679942 28OCT1961 01JAN1960:09:07:00 0:00:25 42 71
312 10315 315 bottles of beer on the wall Option 1 0.1276036776 12JUN1960 01JAN1960:01:54:08 0:00:56 57 42
313 10316 316 bottles of beer on the wall Option 1 0.1270824723 15SEP1960 01JAN1960:03:19:25 0:00:21 85 9
314 10317 317 bottles of beer on the wall Option 1 0.3750520117 13JUN1961 01JAN1960:04:33:09 0:01:15 24 20
315 10318 318 bottles of beer on the wall Option 1 0.5777822102 10DEC1960 01JAN1960:13:32:14 0:00:09 98 28
316 10319 319 bottles of beer on the wall Option 1 0.140476402 27AUG1962 01JAN1960:08:52:46 0:01:08 64 83
317 10320 320 bottles of beer on the wall Option 1 0.2589205551 31MAY1961 01JAN1960:08:33:06 0:00:53 28 98
318 10321 321 bottles of beer on the wall Option 1 0.7350722825 16SEP1962 01JAN1960:05:47:44 0:01:17 79 95
319 10322 322 bottles of beer on the wall Option 1 0.1476364542 15JAN1960 01JAN1960:12:21:20 0:00:20 86 62
320 10323 323 bottles of beer on the wall Option 1 0.8700561099 15MAY1962 01JAN1960:00:47:05 0:00:20 90 15
321 10324 324 bottles of beer on the wall Option 1 0.6408788802 12SEP1962 01JAN1960:11:50:31 0:00:53 41 72
322 10325 325 bottles of beer on the wall Option 1 0.6961101623 27NOV1960 01JAN1960:00:10:49 0:01:17 28 72
323 10326 326 bottles of beer on the wall Option 1 0.1467710059 24FEB1961 01JAN1960:01:13:38 0:00:33 14 5
324 10327 327 bottles of beer on the wall Option 1 0.0215573572 09JUN1961 01JAN1960:11:47:17 0:00:21 57 10
325 10328 328 bottles of beer on the wall Option 1 0.4173900054 25JUL1962 01JAN1960:12:28:20 0:00:23 73 90
326 10329 329 bottles of beer on the wall Option 1 0.6395625713 02NOV1961 01JAN1960:08:49:34 0:00:37 77 79
327 10330 330 bottles of beer on the wall Option 1 0.0091438908 18MAY1962 01JAN1960:05:10:05 0:00:41 15 31
328 10331 331 bottles of beer on the wall Option 1 0.1024675197 11DEC1960 01JAN1960:13:12:57 0:00:23 50 13
329 10332 332 bottles of beer on the wall Option 1 0.057470562 11MAY1961 01JAN1960:03:43:04 0:00:17 48 14
330 10333 333 bottles of beer on the wall Option 1 0.8478633872 21JUL1961 01JAN1960:03:45:42 0:01:31 22 40
331 10334 334 bottles of beer on the wall Option 1 0.3442252541 24JUN1960 01JAN1960:01:19:31 0:00:48 82 25
332 10335 335 bottles of beer on the wall Option 1 0.7338460184 06JUN1962 01JAN1960:03:32:34 0:01:04 6 31
333 10336 336 bottles of beer on the wall Option 1 0.6217917342 09MAR1961 01JAN1960:06:37:39 0:00:50 70 84
334 10337 337 bottles of beer on the wall Option 1 0.6684890807 10OCT1961 01JAN1960:05:34:24 0:01:20 66 18
335 10338 338 bottles of beer on the wall Option 1 0.3695247562 05SEP1962 01JAN1960:00:25:21 0:01:18 48 37
336 10339 339 bottles of beer on the wall Option 1 0.9429265987 06DEC1960 01JAN1960:07:11:17 0:00:38 59 1
337 10340 340 bottles of beer on the wall Option 1 0.9266307265 17JUL1960 01JAN1960:06:33:59 0:00:21 12 13
338 10341 341 bottles of beer on the wall Option 1 0.7280535543 23FEB1961 01JAN1960:05:01:10 0:00:34 73 25
339 10342 342 bottles of beer on the wall Option 1 0.488654495 15AUG1962 01JAN1960:01:24:33 0:00:56 59 25
340 10343 343 bottles of beer on the wall Option 1 0.9526806548 28DEC1960 01JAN1960:07:26:17 0:00:58 97 61
341 10344 344 bottles of beer on the wall Option 1 0.526025336 14JAN1960 01JAN1960:10:02:08 0:00:55 11 77
342 10345 345 bottles of beer on the wall Option 1 0.807215352 03JUL1961 01JAN1960:12:49:47 0:00:01 40 7
343 10346 346 bottles of beer on the wall Option 1 0.9305162979 28FEB1960 01JAN1960:09:46:40 0:00:59 56 28
344 10347 347 bottles of beer on the wall Option 1 0.7591318552 18FEB1962 01JAN1960:13:25:32 0:01:10 41 9
345 10348 348 bottles of beer on the wall Option 1 0.4177664911 11SEP1961 01JAN1960:09:55:17 0:01:39 76 82
346 10349 349 bottles of beer on the wall Option 1 0.4690050443 05DEC1961 01JAN1960:11:05:15 0:01:09 63 40
347 10350 350 bottles of beer on the wall Option 1 0.7541399979 31AUG1961 01JAN1960:12:30:45 0:00:33 57 12
348 10351 351 bottles of beer on the wall Option 1 0.1392844325 17MAR1962 01JAN1960:08:20:38 0:00:41 85 45
349 10352 352 bottles of beer on the wall Option 1 0.1020530235 23DEC1961 01JAN1960:09:46:20 0:00:01 55 56
350 10353 353 bottles of beer on the wall Option 1 0.0257998794 04DEC1961 01JAN1960:09:47:10 0:00:31 100 2
351 10354 354 bottles of beer on the wall Option 1 0.1238113316 20MAR1962 01JAN1960:09:15:30 0:00:01 74 11
352 10355 355 bottles of beer on the wall Option 1 0.4214245292 24NOV1960 01JAN1960:04:24:09 0:01:01 79 83
353 10356 356 bottles of beer on the wall Option 1 0.3243381057 12FEB1961 01JAN1960:00:55:59 0:00:50 30 52
354 10357 357 bottles of beer on the wall Option 1 0.9735697345 24NOV1960 01JAN1960:07:10:56 0:01:33 64 2
355 10358 358 bottles of beer on the wall Option 1 0.4796259461 28JAN1961 01JAN1960:11:51:29 0:01:03 19 29
356 10359 359 bottles of beer on the wall Option 1 0.003359966 01SEP1960 01JAN1960:13:24:25 0:00:09 66 60
357 10360 360 bottles of beer on the wall Option 1 0.5773700334 21JAN1960 01JAN1960:10:15:32 0:00:40 9 21
358 10361 361 bottles of beer on the wall Option 1 0.0792848342 25JAN1962 01JAN1960:06:00:35 0:01:25 73 73
359 10362 362 bottles of beer on the wall Option 1 0.9339359365 30MAY1961 01JAN1960:09:08:13 0:00:56 12 56
360 10363 363 bottles of beer on the wall Option 1 0.3517632132 12FEB1961 01JAN1960:12:07:19 0:00:01 74 69
361 10364 364 bottles of beer on the wall Option 1 0.4088954895 17MAR1961 01JAN1960:08:04:51 0:01:01 70 66
362 10365 365 bottles of beer on the wall Option 1 0.1254259623 30DEC1961 01JAN1960:06:47:12 0:00:01 79 43
363 10366 366 bottles of beer on the wall Option 1 0.9190132958 28MAY1961 01JAN1960:06:35:42 0:00:07 19 31
364 10367 367 bottles of beer on the wall Option 1 0.3033860015 17MAY1962 01JAN1960:05:32:03 0:00:32 57 73
365 10368 368 bottles of beer on the wall Option 1 0.1463442846 02SEP1962 01JAN1960:01:24:29 0:00:53 19 64
366 10369 369 bottles of beer on the wall Option 1 0.5516236343 18JUN1962 01JAN1960:10:52:23 0:00:11 51 40
367 10370 370 bottles of beer on the wall Option 1 0.5205378246 19JAN1960 01JAN1960:06:54:14 0:00:58 2 72
368 10371 371 bottles of beer on the wall Option 1 0.9941610768 28MAR1962 01JAN1960:04:55:58 0:00:22 46 65
369 10372 372 bottles of beer on the wall Option 1 0.065678 07MAY1961 01JAN1960:10:17:35 0:00:10 54 100
370 10373 373 bottles of beer on the wall Option 1 0.7222646138 17JUL1961 01JAN1960:01:47:32 0:00:51 26 96
371 10374 374 bottles of beer on the wall Option 1 0.8772228294 23JUL1960 01JAN1960:00:30:51 0:00:40 18 45
372 10375 375 bottles of beer on the wall Option 1 0.3651081847 11DEC1961 01JAN1960:00:46:15 0:00:15 14 90
373 10376 376 bottles of beer on the wall Option 1 0.3800431529 15AUG1960 01JAN1960:05:30:55 0:00:19 13 74
374 10377 377 bottles of beer on the wall Option 1 0.1077003503 26FEB1960 01JAN1960:04:48:40 0:00:08 51 53
375 10378 378 bottles of beer on the wall Option 1 0.7945664035 06MAR1961 01JAN1960:05:36:47 0:00:45 65 39
376 10379 379 bottles of beer on the wall Option 1 0.8754883054 06JUN1960 01JAN1960:06:09:33 0:00:04 3 3
377 10380 380 bottles of beer on the wall Option 1 0.9975561108 10AUG1960 01JAN1960:10:34:33 0:00:28 92 29
378 10381 381 bottles of beer on the wall Option 1 0.9817031599 07JUL1960 01JAN1960:01:40:00 0:00:39 63 45
379 10382 382 bottles of beer on the wall Option 1 0.4427802341 07JAN1962 01JAN1960:01:21:32 0:01:31 7 54
380 10383 383 bottles of beer on the wall Option 1 0.03180474 17JUL1962 01JAN1960:07:15:54 0:01:08 72 60
381 10384 384 bottles of beer on the wall Option 1 0.1031627707 10MAY1962 01JAN1960:02:52:58 0:01:31 6 64
382 10385 385 bottles of beer on the wall Option 1 0.911744344 01MAY1960 01JAN1960:03:51:16 0:01:04 1 54
383 10386 386 bottles of beer on the wall Option 1 0.4912374353 13FEB1961 01JAN1960:07:22:49 0:01:21 70 71
384 10387 387 bottles of beer on the wall Option 1 0.8803869509 04JUL1960 01JAN1960:12:14:05 0:00:18 78 88
385 10388 388 bottles of beer on the wall Option 1 0.0596609544 17DEC1960 01JAN1960:08:29:20 0:00:53 13 84
386 10389 389 bottles of beer on the wall Option 1 0.6625022132 12JAN1961 01JAN1960:11:15:39 0:01:05 10 31
387 10390 390 bottles of beer on the wall Option 1 0.2669677358 05OCT1961 01JAN1960:00:48:03 0:01:33 29 31
388 10391 391 bottles of beer on the wall Option 1 0.8095563454 04DEC1961 01JAN1960:07:54:13 0:01:15 95 2
389 10392 392 bottles of beer on the wall Option 1 0.6406704796 27JAN1961 01JAN1960:03:35:55 0:00:36 92 47
390 10393 393 bottles of beer on the wall Option 1 0.2188341847 02MAR1960 01JAN1960:04:05:21 0:00:11 28 34
391 10394 394 bottles of beer on the wall Option 1 0.7052043424 09JUN1962 01JAN1960:07:00:21 0:01:14 84 19
392 10395 395 bottles of beer on the wall Option 1 0.9843204464 18APR1960 01JAN1960:04:54:31 0:01:29 46 46
393 10396 396 bottles of beer on the wall Option 1 0.329249541 10SEP1961 01JAN1960:13:21:04 0:00:21 70 11
394 10397 397 bottles of beer on the wall Option 1 0.2073628675 13JUL1962 01JAN1960:11:16:26 0:01:23 17 97
395 10398 398 bottles of beer on the wall Option 1 0.7881676665 29JUN1962 01JAN1960:11:36:47 0:00:50 39 72
396 10399 399 bottles of beer on the wall Option 1 0.4347905537 31AUG1962 01JAN1960:02:30:30 0:00:21 86 61
397 10400 400 bottles of beer on the wall Option 1 0.2937454084 05APR1962 01JAN1960:02:44:06 0:00:32 27 81
398 10401 401 bottles of beer on the wall Option 1 0.6659902565 10APR1961 01JAN1960:11:53:59 0:00:01 80 17
399 10402 402 bottles of beer on the wall Option 1 0.7637229686 07APR1962 01JAN1960:05:45:25 0:01:28 11 17
400 10403 403 bottles of beer on the wall Option 1 0.3325480941 19MAR1961 01JAN1960:09:57:05 0:00:27 9 99
401 10404 404 bottles of beer on the wall Option 1 0.580015553 10AUG1960 01JAN1960:06:15:44 0:00:25 27 99
402 10405 405 bottles of beer on the wall Option 1 0.2514696071 08APR1961 01JAN1960:10:37:45 0:00:17 29 59
403 10406 406 bottles of beer on the wall Option 1 0.3792107284 19MAR1962 01JAN1960:04:49:30 0:00:07 44 38
404 10407 407 bottles of beer on the wall Option 1 0.4702913125 13DEC1961 01JAN1960:09:03:31 0:00:38 95 90
405 10408 408 bottles of beer on the wall Option 1 0.4207190659 03FEB1961 01JAN1960:00:37:47 0:00:38 37 65
406 10409 409 bottles of beer on the wall Option 1 0.2485069117 08DEC1961 01JAN1960:07:18:28 0:01:39 91 64
407 10410 410 bottles of beer on the wall Option 1 0.3257893502 27NOV1961 01JAN1960:11:33:02 0:00:54 41 7
408 10411 411 bottles of beer on the wall Option 1 0.0967283533 11AUG1962 01JAN1960:07:23:15 0:00:21 90 1
409 10412 412 bottles of beer on the wall Option 1 0.532676542 01SEP1960 01JAN1960:02:46:29 0:00:45 31 48
410 10413 413 bottles of beer on the wall Option 1 0.2564602151 15JAN1961 01JAN1960:01:09:11 0:01:21 16 89
411 10414 414 bottles of beer on the wall Option 1 0.0865634024 20MAR1962 01JAN1960:12:56:45 0:00:05 75 51
412 10415 415 bottles of beer on the wall Option 1 0.2926342321 07FEB1960 01JAN1960:06:48:55 0:00:36 66 33
413 10416 416 bottles of beer on the wall Option 1 0.0678594029 06OCT1961 01JAN1960:07:14:58 0:01:26 50 16
414 10417 417 bottles of beer on the wall Option 1 0.6376664767 09JUN1960 01JAN1960:05:00:13 0:01:37 7 92
415 10418 418 bottles of beer on the wall Option 1 0.4795483525 14JUN1962 01JAN1960:00:00:50 0:00:50 33 74
416 10419 419 bottles of beer on the wall Option 1 0.3492934342 22MAR1960 01JAN1960:08:54:52 0:01:26 61 72
417 10420 420 bottles of beer on the wall Option 1 0.5085071356 14MAR1960 01JAN1960:09:47:51 0:00:56 36 63
418 10421 421 bottles of beer on the wall Option 1 0.414953564 25MAR1961 01JAN1960:03:35:19 0:00:30 47 30
419 10422 422 bottles of beer on the wall Option 1 0.2431976652 25SEP1960 01JAN1960:08:47:25 0:00:17 6 42
420 10423 423 bottles of beer on the wall Option 1 0.2370444998 04MAR1962 01JAN1960:00:16:44 0:01:36 54 100
421 10424 424 bottles of beer on the wall Option 1 0.8687893324 12OCT1961 01JAN1960:03:16:33 0:00:56 97 25
422 10425 425 bottles of beer on the wall Option 1 0.0470510335 10MAY1960 01JAN1960:02:44:07 0:01:05 83 59
423 10426 426 bottles of beer on the wall Option 1 0.7114342887 12APR1960 01JAN1960:02:17:40 0:00:39 57 97
424 10427 427 bottles of beer on the wall Option 1 0.6176668283 05JUL1962 01JAN1960:09:09:12 0:01:03 92 38
425 10428 428 bottles of beer on the wall Option 1 0.0657907743 01JUL1962 01JAN1960:11:03:37 0:01:35 97 63
426 10429 429 bottles of beer on the wall Option 1 0.280104912 13MAR1962 01JAN1960:10:35:08 0:01:07 42 35
427 10430 430 bottles of beer on the wall Option 1 0.3639827088 02APR1960 01JAN1960:12:00:50 0:00:40 91 84
428 10431 431 bottles of beer on the wall Option 1 0.2130561137 25AUG1961 01JAN1960:12:07:22 0:01:37 70 9
429 10432 432 bottles of beer on the wall Option 1 0.9656705889 23DEC1960 01JAN1960:02:36:48 0:01:28 23 92
430 10433 433 bottles of beer on the wall Option 1 0.5824601052 22JAN1961 01JAN1960:01:19:48 0:00:32 73 6
431 10434 434 bottles of beer on the wall Option 1 0.5207124942 23APR1961 01JAN1960:10:45:16 0:01:08 45 85
432 10435 435 bottles of beer on the wall Option 1 0.9280530661 01NOV1960 01JAN1960:12:46:59 0:01:36 57 4
433 10436 436 bottles of beer on the wall Option 1 0.8982810149 29NOV1961 01JAN1960:09:23:13 0:01:15 100 68
434 10437 437 bottles of beer on the wall Option 1 0.3268259467 04MAR1960 01JAN1960:01:22:42 0:00:04 99 61
435 10438 438 bottles of beer on the wall Option 1 0.2038002704 12FEB1962 01JAN1960:09:03:24 0:00:40 97 78
436 10439 439 bottles of beer on the wall Option 1 0.0798850833 11MAY1960 01JAN1960:00:32:50 0:00:37 7 49
437 10440 440 bottles of beer on the wall Option 1 0.6697000566 01SEP1960 01JAN1960:08:04:03 0:00:30 7 68
438 10441 441 bottles of beer on the wall Option 1 0.550699767 11JAN1960 01JAN1960:06:33:15 0:01:09 19 10
439 10442 442 bottles of beer on the wall Option 1 0.9514032798 07FEB1962 01JAN1960:06:03:16 0:01:13 65 87
440 10443 443 bottles of beer on the wall Option 1 0.1182718324 08FEB1960 01JAN1960:11:28:52 0:00:46 61 59
441 10444 444 bottles of beer on the wall Option 1 0.5772118874 11FEB1962 01JAN1960:01:14:29 0:01:07 16 22
442 10445 445 bottles of beer on the wall Option 1 0.9828714463 06DEC1960 01JAN1960:05:47:08 0:01:40 66 4
443 10446 446 bottles of beer on the wall Option 1 0.1229167269 02JUN1960 01JAN1960:09:43:51 0:01:34 29 24
444 10447 447 bottles of beer on the wall Option 1 0.2102257522 09MAR1961 01JAN1960:04:06:09 0:01:27 53 78
445 10448 448 bottles of beer on the wall Option 1 0.9958884935 20FEB1962 01JAN1960:06:43:53 0:00:07 42 65
446 10449 449 bottles of beer on the wall Option 1 0.3530408085 04MAY1961 01JAN1960:11:26:59 0:01:37 76 35
447 10450 450 bottles of beer on the wall Option 1 0.2848354258 03SEP1960 01JAN1960:13:26:36 0:00:25 69 38
448 10451 451 bottles of beer on the wall Option 1 0.1461860818 10JUN1960 01JAN1960:01:24:25 0:00:02 61 23
449 10452 452 bottles of beer on the wall Option 1 0.2033735766 29AUG1960 01JAN1960:12:30:17 0:00:19 32 75
450 10453 453 bottles of beer on the wall Option 1 0.7973149958 26JUN1961 01JAN1960:04:46:06 0:00:21 94 14
451 10454 454 bottles of beer on the wall Option 1 0.6812086425 07NOV1961 01JAN1960:01:59:51 0:00:12 89 59
452 10455 455 bottles of beer on the wall Option 1 0.6111464974 24FEB1962 01JAN1960:07:42:56 0:00:15 23 92
453 10456 456 bottles of beer on the wall Option 1 0.9542484209 09APR1961 01JAN1960:09:09:17 0:01:26 87 93
454 10457 457 bottles of beer on the wall Option 1 0.9818577077 18AUG1960 01JAN1960:12:24:47 0:01:08 18 20
455 10458 458 bottles of beer on the wall Option 1 0.9331120881 06JUL1961 01JAN1960:10:10:02 0:01:40 78 36
456 10459 459 bottles of beer on the wall Option 1 0.8953045587 22APR1960 01JAN1960:04:47:34 0:00:37 13 46
457 10460 460 bottles of beer on the wall Option 1 0.1584420461 08JAN1961 01JAN1960:07:47:49 0:00:05 85 61
458 10461 461 bottles of beer on the wall Option 1 0.9324573814 24DEC1960 01JAN1960:02:13:36 0:00:22 55 94
459 10462 462 bottles of beer on the wall Option 1 0.0813189871 21AUG1961 01JAN1960:09:18:28 0:00:36 42 49
460 10463 463 bottles of beer on the wall Option 1 0.8736312594 17MAY1962 01JAN1960:12:52:58 0:00:30 45 7
461 10464 464 bottles of beer on the wall Option 1 0.1894013794 06NOV1960 01JAN1960:12:56:13 0:01:30 11 50
462 10465 465 bottles of beer on the wall Option 1 0.9149773772 07JUN1960 01JAN1960:08:53:28 0:00:22 23 17
463 10466 466 bottles of beer on the wall Option 1 0.6329479598 27JUN1962 01JAN1960:07:38:23 0:00:06 68 14
464 10467 467 bottles of beer on the wall Option 1 0.1897066413 21AUG1961 01JAN1960:10:15:28 0:01:12 59 46
465 10468 468 bottles of beer on the wall Option 1 0.8352205767 16MAR1961 01JAN1960:06:48:50 0:00:44 60 37
466 10469 469 bottles of beer on the wall Option 1 0.3339443432 09OCT1960 01JAN1960:00:52:53 0:00:27 70 44
467 10470 470 bottles of beer on the wall Option 1 0.1096137567 09JUL1962 01JAN1960:08:28:10 0:01:15 88 81
468 10471 471 bottles of beer on the wall Option 1 0.1481936733 10JAN1962 01JAN1960:06:38:41 0:00:56 21 77
469 10472 472 bottles of beer on the wall Option 1 0.5630390432 01MAR1960 01JAN1960:06:35:09 0:01:08 70 32
470 10473 473 bottles of beer on the wall Option 1 0.0604085713 12APR1962 01JAN1960:02:41:26 0:00:46 36 17
471 10474 474 bottles of beer on the wall Option 1 0.6011423606 25DEC1961 01JAN1960:02:57:45 0:01:11 36 18
472 10475 475 bottles of beer on the wall Option 1 0.7698335782 31JUL1962 01JAN1960:07:46:29 0:01:34 72 17
473 10476 476 bottles of beer on the wall Option 1 0.3823641224 17MAR1962 01JAN1960:03:34:37 0:00:09 27 86
474 10477 477 bottles of beer on the wall Option 1 0.9225378446 12JAN1962 01JAN1960:08:41:25 0:01:06 45 20
475 10478 478 bottles of beer on the wall Option 1 0.2979750453 23JUN1962 01JAN1960:10:06:36 0:01:28 88 7
476 10479 479 bottles of beer on the wall Option 1 0.4988665942 15JUL1961 01JAN1960:02:33:06 0:01:33 85 1
477 10480 480 bottles of beer on the wall Option 1 0.5243853585 29JUL1960 01JAN1960:00:26:18 0:00:31 48 77
478 10481 481 bottles of beer on the wall Option 1 0.6049248826 12JUL1962 01JAN1960:10:01:41 0:00:16 66 45
479 10482 482 bottles of beer on the wall Option 1 0.6312438024 01OCT1961 01JAN1960:05:18:12 0:00:04 43 27
480 10483 483 bottles of beer on the wall Option 1 0.3366865974 17MAY1962 01JAN1960:01:44:17 0:00:01 31 25
481 10484 484 bottles of beer on the wall Option 1 0.0813266188 08AUG1962 01JAN1960:06:18:27 0:00:08 71 63
482 10485 485 bottles of beer on the wall Option 1 0.3601163455 23JAN1962 01JAN1960:11:26:01 0:00:37 41 88
483 10486 486 bottles of beer on the wall Option 1 0.9033777345 13AUG1961 01JAN1960:00:16:14 0:00:56 82 33
484 10487 487 bottles of beer on the wall Option 1 0.1716986667 23DEC1960 01JAN1960:12:06:34 0:01:13 2 32
485 10488 488 bottles of beer on the wall Option 1 0.9734818912 11SEP1961 01JAN1960:00:34:41 0:00:28 17 7
486 10489 489 bottles of beer on the wall Option 1 0.0618140223 17DEC1961 01JAN1960:06:26:30 0:00:38 94 40
487 10490 490 bottles of beer on the wall Option 1 0.0204490144 22AUG1960 01JAN1960:01:50:18 0:00:19 40 56
488 10491 491 bottles of beer on the wall Option 1 0.8719323929 23MAY1960 01JAN1960:12:36:06 0:00:08 49 44
489 10492 492 bottles of beer on the wall Option 1 0.2656292181 28JUN1962 01JAN1960:05:32:50 0:01:35 15 39
490 10493 493 bottles of beer on the wall Option 1 0.37794835 23JUL1962 01JAN1960:13:15:43 0:00:56 6 86
491 10494 494 bottles of beer on the wall Option 1 0.6395865733 17JAN1961 01JAN1960:12:20:12 0:01:31 22 87
492 10495 495 bottles of beer on the wall Option 1 0.4408595098 05JUL1960 01JAN1960:12:21:53 0:01:40 25 27
493 10496 496 bottles of beer on the wall Option 1 0.4846261169 02DEC1961 01JAN1960:12:41:08 0:00:06 7 63
494 10497 497 bottles of beer on the wall Option 1 0.7903671478 14MAY1962 01JAN1960:05:09:21 0:01:03 98 25
495 10498 498 bottles of beer on the wall Option 1 0.60474184 13OCT1961 01JAN1960:03:52:59 0:01:22 98 98
496 10499 499 bottles of beer on the wall Option 1 0.1213259218 23APR1962 01JAN1960:06:29:47 0:01:35 38 70
497 10500 500 bottles of beer on the wall Option 1 0.7882370487 17FEB1962 01JAN1960:02:00:25 0:00:12 1 74

View File

@ -15,6 +15,9 @@ context('editor tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -115,6 +118,10 @@ context('editor tests: ', function () {
}) })
}) })
}) })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const clickOnEdit = (callback?: any) => { const clickOnEdit = (callback?: any) => {
@ -214,10 +221,14 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if (approvalButton.innerText.toLowerCase().includes('approve')) { if (
approvalButton.innerText
.toLowerCase()
.includes('go to approvals screen')
) {
approvalButton.click() approvalButton.click()
break break
} }

View File

@ -19,6 +19,9 @@ context('excel tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
@ -336,6 +339,7 @@ context('excel tests: ', function () {
this.afterEach(() => { this.afterEach(() => {
colorLog(`TEST END -------------`, '#3498DB') colorLog(`TEST END -------------`, '#3498DB')
// cy.visit(`${hostUrl}/SASLogon/logout`)
}) })
}) })
@ -403,10 +407,14 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if (approvalButton.innerText.toLowerCase().includes('approve')) { if (
approvalButton.innerText
.toLowerCase()
.includes('go to approvals screen')
) {
approvalButton.click() approvalButton.click()
break break
} }
@ -432,10 +440,14 @@ const rejectExcel = (callback?: any) => {
const acceptExcel = (callback?: any) => { const acceptExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if (approvalButton.innerText.toLowerCase().includes('approve')) { if (
approvalButton.innerText
.toLowerCase()
.includes('go to approvals screen')
) {
approvalButton.click() approvalButton.click()
break break
} }

View File

@ -15,6 +15,9 @@ context('filtering tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout }) cy.visit(hostUrl + appLocation, { timeout: longerCommandTimeout })
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -170,6 +173,10 @@ context('filtering tests: ', function () {
}) })
}) })
}) })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const checkInfoBarIncludes = (text: string, callback: any) => { const checkInfoBarIncludes = (text: string, callback: any) => {

View File

@ -23,11 +23,15 @@ interface EditConfigTableCells {
context('licensing tests: ', function () { context('licensing tests: ', function () {
this.beforeAll(() => { this.beforeAll(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
cy.loginAndUpdateValidKey() cy.loginAndUpdateValidKey()
}) })
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -370,6 +374,10 @@ context('licensing tests: ', function () {
}) })
}) })
} }
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const logout = (callback?: any) => { const logout = (callback?: any) => {
@ -691,10 +699,14 @@ const submitTable = (callback?: any) => {
const approveTable = (callback?: any) => { const approveTable = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if (approvalButton.innerText.toLowerCase().includes('approve')) { if (
approvalButton.innerText
.toLowerCase()
.includes('go to approvals screen')
) {
approvalButton.click() approvalButton.click()
break break
} }

View File

@ -18,6 +18,10 @@ context('liveness tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
// cy.get('input.username').type(username)
// cy.get('input.password').type(password)
// cy.get('.login-group button').click()
visitPage('home') visitPage('home')
}) })
@ -121,10 +125,14 @@ const submitExcel = (callback?: any) => {
const rejectExcel = (callback?: any) => { const rejectExcel = (callback?: any) => {
cy.get('button', { timeout: longerCommandTimeout }) cy.get('button', { timeout: longerCommandTimeout })
.should('contain', 'Approve') .should('contain', 'Go to approvals screen')
.then((allButtons: any) => { .then((allButtons: any) => {
for (let approvalButton of allButtons) { for (let approvalButton of allButtons) {
if (approvalButton.innerText.toLowerCase().includes('approve')) { if (
approvalButton.innerText
.toLowerCase()
.includes('go to approvals screen')
) {
approvalButton.click() approvalButton.click()
break break
} }

View File

@ -17,6 +17,7 @@ context('editor tests: ', function () {
this.beforeEach(() => { this.beforeEach(() => {
cy.visit(hostUrl + appLocation) cy.visit(hostUrl + appLocation)
cy.wait(2000) cy.wait(2000)
cy.get('body').then(($body) => { cy.get('body').then(($body) => {
@ -385,6 +386,10 @@ context('editor tests: ', function () {
} }
) )
}) })
this.afterEach(() => {
// cy.visit(`${hostUrl}/SASLogon/logout`)
})
}) })
const checkColumns = (columns: string[], callback: () => void) => { const checkColumns = (columns: string[], callback: () => void) => {

View File

@ -6,8 +6,5 @@
"lib": ["es2019", "dom"], "lib": ["es2019", "dom"],
"types": ["cypress", "cypress-real-events"] "types": ["cypress", "cypress-real-events"]
}, },
"include": [ "include": ["**/*.ts"]
"**/*.ts",
"../cypress.config.ts"
]
} }

Binary file not shown.

View File

@ -10,7 +10,7 @@ const check = (cwd) => {
onlyAllow: onlyAllow:
'AFLv2.1;Apache 2.0;Apache-2.0;Apache*;Artistic-2.0;0BSD;BSD*;BSD-2-Clause;BSD-3-Clause;CC0-1.0;CC-BY-3.0;CC-BY-4.0;ISC;MIT;MPL-2.0;ODC-By-1.0;Python-2.0;Unlicense;', 'AFLv2.1;Apache 2.0;Apache-2.0;Apache*;Artistic-2.0;0BSD;BSD*;BSD-2-Clause;BSD-3-Clause;CC0-1.0;CC-BY-3.0;CC-BY-4.0;ISC;MIT;MPL-2.0;ODC-By-1.0;Python-2.0;Unlicense;',
excludePackages: excludePackages:
'@cds/city@1.1.0;@handsontable/angular@15.3.0;handsontable@15.3.0;hyperformula@2.7.1;hyperformula@3.0.0;jackspeak@3.4.3;path-scurry@1.11.1;package-json-from-dist@1.0.1' '@cds/city@1.1.0;@handsontable/angular@13.1.0;handsontable@13.1.0;hyperformula@2.6.0;jackspeak@2.2.0;path-scurry@1.7.0'
}, },
(error, json) => { (error, json) => {
if (error) { if (error) {

16334
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@
"deploy_sasjs": "rsync -avhe ssh ./dist/* --delete root@${npm_config_account}.4gl.io:/var/www/html/dc/dev", "deploy_sasjs": "rsync -avhe ssh ./dist/* --delete root@${npm_config_account}.4gl.io:/var/www/html/dc/dev",
"viyabuild": "cd build; ./viyabuild.sh", "viyabuild": "cd build; ./viyabuild.sh",
"lint": "cd .. && npm run lint", "lint": "cd .. && npm run lint",
"test": "npx ng test", "test": "ng test",
"test:headless": "npx ng test --no-watch --no-progress --browsers ChromeHeadlessCI", "test:headless": "ng test --browsers ChromeHeadless",
"watch": "ng test watch=true", "watch": "ng test watch=true",
"pree2e": "webdriver-manager update", "pree2e": "webdriver-manager update",
"e2e": "protractor protractor.config.js", "e2e": "protractor protractor.config.js",
@ -35,32 +35,32 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "^17.3.3", "@angular/animations": "^16.1.2",
"@angular/cdk": "^17.3.3", "@angular/cdk": "^15.2.0",
"@angular/common": "^17.3.3", "@angular/common": "^16.1.2",
"@angular/compiler": "^17.3.3", "@angular/compiler": "^16.1.2",
"@angular/core": "^17.3.3", "@angular/core": "^16.1.2",
"@angular/forms": "^17.3.3", "@angular/forms": "^16.1.2",
"@angular/platform-browser": "^17.3.3", "@angular/platform-browser": "^16.1.2",
"@angular/platform-browser-dynamic": "^17.3.3", "@angular/platform-browser-dynamic": "^16.1.2",
"@angular/router": "^17.3.3", "@angular/router": "^16.1.2",
"@cds/core": "^6.15.1", "@cds/core": "^6.4.2",
"@clr/angular": "file:libraries/clr-angular-17.9.0.tgz", "@clr/angular": "^13.17.0",
"@clr/icons": "^13.0.2", "@clr/icons": "^13.0.2",
"@clr/ui": "file:libraries/clr-ui-17.9.0.tgz", "@clr/ui": "^13.17.0",
"@handsontable/angular": "^15.3.0", "@handsontable/angular": "^13.1.0",
"@sasjs/adapter": "^4.11.0", "@sasjs/adapter": "4.10.1",
"@sasjs/utils": "^3.4.0", "@sasjs/utils": "^3.4.0",
"@sheet/crypto": "file:libraries/sheet-crypto.tgz", "@sheet/crypto": "1.20211122.1",
"@types/d3-graphviz": "^2.6.7", "@types/d3-graphviz": "^2.6.7",
"@types/text-encoding": "0.0.35", "@types/text-encoding": "0.0.35",
"base64-arraybuffer": "^0.2.0", "base64-arraybuffer": "^0.2.0",
"buffer": "^5.4.3", "buffer": "^5.4.3",
"crypto-browserify": "^3.12.1", "crypto-browserify": "3.12.0",
"crypto-js": "^4.2.0", "crypto-js": "^3.3.0",
"d3-graphviz": "^5.0.2", "d3-graphviz": "^5.0.2",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",
"handsontable": "^15.3.0", "handsontable": "^13.1.0",
"https-browserify": "1.0.0", "https-browserify": "1.0.0",
"hyperformula": "^2.5.0", "hyperformula": "^2.5.0",
"iconv-lite": "^0.5.0", "iconv-lite": "^0.5.0",
@ -78,27 +78,24 @@
"stream-http": "3.2.0", "stream-http": "3.2.0",
"text-encoding": "^0.7.0", "text-encoding": "^0.7.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"vm": "^0.1.0", "zone.js": "~0.13.0"
"webpack": "^5.91.0",
"xlsx": "^0.18.5",
"zone.js": "~0.14.4"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^17.3.3", "@angular-devkit/build-angular": "^16.1.0",
"@angular-eslint/builder": "17.3.0", "@angular-eslint/builder": "16.0.3",
"@angular-eslint/eslint-plugin": "17.3.0", "@angular-eslint/eslint-plugin": "16.0.3",
"@angular-eslint/eslint-plugin-template": "17.3.0", "@angular-eslint/eslint-plugin-template": "16.0.3",
"@angular-eslint/schematics": "17.3.0", "@angular-eslint/schematics": "16.0.3",
"@angular-eslint/template-parser": "17.3.0", "@angular-eslint/template-parser": "16.0.3",
"@angular/cli": "^17.3.3", "@angular/cli": "^16.1.0",
"@angular/compiler-cli": "^17.3.3", "@angular/compiler-cli": "^16.1.2",
"@babel/plugin-proposal-private-methods": "^7.18.6", "@babel/plugin-proposal-private-methods": "^7.18.6",
"@compodoc/compodoc": "^1.1.21", "@compodoc/compodoc": "^1.1.21",
"@cypress/webpack-preprocessor": "^5.17.1", "@cypress/webpack-preprocessor": "^5.17.1",
"@types/core-js": "^2.5.5", "@types/core-js": "^2.5.5",
"@types/crypto-js": "^4.2.1", "@types/crypto-js": "^4.0.1",
"@types/es6-shim": "^0.31.39", "@types/es6-shim": "^0.31.39",
"@types/jasmine": "~5.1.4", "@types/jasmine": "~3.6.0",
"@types/lodash-es": "^4.17.3", "@types/lodash-es": "^4.17.3",
"@types/marked": "^4.3.0", "@types/marked": "^4.3.0",
"@types/node": "12.20.50", "@types/node": "12.20.50",
@ -112,12 +109,12 @@
"es6-shim": "^0.35.5", "es6-shim": "^0.35.5",
"eslint": "^8.33.0", "eslint": "^8.33.0",
"git-describe": "^4.0.4", "git-describe": "^4.0.4",
"jasmine-core": "~5.1.2", "jasmine-core": "~3.6.0",
"karma": "~6.4.3", "karma": "~6.3.0",
"karma-chrome-launcher": "~3.2.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.2.1", "karma-coverage": "~2.1.0",
"karma-jasmine": "~5.1.0", "karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~2.1.0", "karma-jasmine-html-reporter": "~1.7.0",
"license-checker": "25.0.1", "license-checker": "25.0.1",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mochawesome": "^7.1.3", "mochawesome": "^7.1.3",
@ -126,7 +123,9 @@
"rimraf": "3.0.2", "rimraf": "3.0.2",
"ts-loader": "^9.2.8", "ts-loader": "^9.2.8",
"ts-node": "^3.3.0", "ts-node": "^3.3.0",
"typescript": "~5.4.4", "typedoc": "^0.24.8",
"typedoc-plugin-external-module-name": "^4.0.6",
"typescript": "~4.9.4",
"wait-on": "^6.0.1", "wait-on": "^6.0.1",
"watch": "^1.0.2" "watch": "^1.0.2"
} }

View File

@ -37,16 +37,6 @@ export const initFilter: { filter: FilterCache } = {
} }
} }
export interface XLMapListItem {
id: string
description: string
targetDS: string
}
export interface HandsontableStaticConfig {
darkTableHeaderClass: string
}
/** /**
* Cached filtering values across whole app (editor, viewer, viewboxes) * Cached filtering values across whole app (editor, viewer, viewboxes)
* Cached lineage libraries, tables * Cached lineage libraries, tables
@ -56,8 +46,6 @@ export interface HandsontableStaticConfig {
*/ */
export const globals: { export const globals: {
rootParam: string rootParam: string
dcLib: string
xlmaps: XLMapListItem[]
editor: any editor: any
viewer: any viewer: any
viewboxes: ViewboxCache viewboxes: ViewboxCache
@ -66,17 +54,14 @@ export const globals: {
viyaApi: any viyaApi: any
usernav: any usernav: any
operators: any operators: any
handsontable: HandsontableStaticConfig
[key: string]: any [key: string]: any
} = { } = {
rootParam: <string>'', rootParam: <string>'',
dcLib: '',
xlmaps: [],
editor: { editor: {
startupSet: <boolean>false, startupSet: <boolean>false,
treeNodeLibraries: <any[] | null>[], treeNodeLibraries: <any[] | null>[],
libsAndTables: <any[]>[], libsAndTables: <any[]>[],
libraries: <string[] | undefined>[], libraries: <String[] | undefined>[],
library: <string>'', library: <string>'',
table: <string>'', table: <string>'',
filter: <FilterCache>{ filter: <FilterCache>{
@ -145,11 +130,5 @@ export const globals: {
operators: { operators: {
numOperators: ['=', '<', '>', '<=', '>=', 'BETWEEN', 'IN', 'NOT IN', 'NE'], numOperators: ['=', '<', '>', '<=', '>=', 'BETWEEN', 'IN', 'NOT IN', 'NE'],
charOperators: ['=', '<', '>', '<=', '>=', 'CONTAINS', 'IN', 'NOT IN', 'NE'] charOperators: ['=', '<', '>', '<=', '>=', 'CONTAINS', 'IN', 'NOT IN', 'NE']
},
handsontable: {
darkTableHeaderClass: 'darkTH'
},
userDropdownConfig: {
closeOnDebugClick: false
} }
} }

View File

@ -12,7 +12,7 @@
<div class="alert-items"> <div class="alert-items">
<div class="alert-item static"> <div class="alert-item static">
<div class="alert-icon-wrapper"> <div class="alert-icon-wrapper">
<cds-icon class="alert-icon" shape="warning-standard"></cds-icon> <clr-icon class="mt-2" shape="warning-standard"></clr-icon>
</div> </div>
<div class="alert-text"> <div class="alert-text">
Data Controller (FREE Tier) - to upgrade contact Data Controller (FREE Tier) - to upgrade contact
@ -30,7 +30,7 @@
<div class="alert-items"> <div class="alert-items">
<div class="alert-item static"> <div class="alert-item static">
<div class="alert-icon-wrapper"> <div class="alert-icon-wrapper">
<cds-icon class="alert-icon" shape="warning-standard"></cds-icon> <clr-icon class="mt-2" shape="warning-standard"></clr-icon>
</div> </div>
<div class="alert-text"> <div class="alert-text">
Data Controller (FREE Tier) - Problem with licence Data Controller (FREE Tier) - Problem with licence
@ -55,7 +55,7 @@
<div class="alert-items"> <div class="alert-items">
<div class="alert-item static"> <div class="alert-item static">
<div class="alert-icon-wrapper"> <div class="alert-icon-wrapper">
<cds-icon class="alert-icon" shape="warning-standard"></cds-icon> <clr-icon class="mt-2" shape="warning-standard"></clr-icon>
</div> </div>
<div class="alert-text"> <div class="alert-text">
@ -85,7 +85,7 @@
<div class="alert-items"> <div class="alert-items">
<div class="alert-item static"> <div class="alert-item static">
<div class="alert-icon-wrapper"> <div class="alert-icon-wrapper">
<cds-icon class="alert-icon" shape="warning-standard"></cds-icon> <clr-icon class="mt-2" shape="warning-standard"></clr-icon>
</div> </div>
<div class="alert-text"> <div class="alert-text">
@ -139,15 +139,10 @@
[routerLink]="['/']" [routerLink]="['/']"
class="nav-link" class="nav-link"
> >
<img <img class="without-text d-block d-md-none" src="images/dc-logo.svg" />
class="without-text d-block d-md-none"
src="images/dc-logo.svg"
alt="datacontroller logo without text"
/>
<img <img
class="with-text d-none d-md-block" class="with-text d-none d-md-block"
src="images/datacontroller.svg" src="images/datacontroller.svg"
alt="datacontroller logo"
/> />
</a> </a>
@ -173,7 +168,7 @@
</button> </button>
<clr-dropdown-menu *clrIfOpen clrPosition="bottom-left"> <clr-dropdown-menu *clrIfOpen clrPosition="bottom-left">
<a [routerLink]="['/view']" clrDropdownItem>VIEW</a> <a [routerLink]="['/view']" clrDropdownItem>VIEW</a>
<a [routerLink]="['/home']" clrDropdownItem>LOAD</a> <a [routerLink]="['/home']" clrDropdownItem>EDIT</a>
<a [routerLink]="['/review/submitted']" clrDropdownItem>REVIEW</a> <a [routerLink]="['/review/submitted']" clrDropdownItem>REVIEW</a>
</clr-dropdown-menu> </clr-dropdown-menu>
</clr-dropdown> </clr-dropdown>
@ -194,7 +189,7 @@
router.url.includes('edit-record') || router.url.includes('edit-record') ||
router.url.includes('home') router.url.includes('home')
" "
>LOAD</a >EDIT</a
> >
<a <a
[routerLink]="['/review/submitted']" [routerLink]="['/review/submitted']"
@ -209,7 +204,14 @@
</div> </div>
</ng-container> </ng-container>
<app-header-actions></app-header-actions> <div class="header-actions">
<div class="nav-text">
<app-loading-indicator></app-loading-indicator>
</div>
<div class="dropdown">
<app-user-nav-dropdown></app-user-nav-dropdown>
</div>
</div>
</header> </header>
<nav <nav
*ngIf=" *ngIf="
@ -250,7 +252,6 @@
<app-alerts *ngIf="!errTop"></app-alerts> <app-alerts *ngIf="!errTop"></app-alerts>
<app-requests-modal [(opened)]="requestsModal"></app-requests-modal> <app-requests-modal [(opened)]="requestsModal"></app-requests-modal>
<app-excel-password-modal></app-excel-password-modal>
<!-- <app-terms *ngIf="showRegistration"></app-terms> --> <!-- <app-terms *ngIf="showRegistration"></app-terms> -->
@ -288,11 +289,7 @@
<!-- App Loading Page --> <!-- App Loading Page -->
<div *ngIf="!startupDataLoaded" class="app-loading"> <div *ngIf="!startupDataLoaded" class="app-loading">
<img <img class="loading-logo" src="images/datacontroller.svg" />
class="loading-logo"
src="images/datacontroller.svg"
alt="datacontroller logo"
/>
<div *ngIf="appActive === null" class="slider"> <div *ngIf="appActive === null" class="slider">
<div class="line"></div> <div class="line"></div>

View File

@ -0,0 +1,461 @@
// Copyright (c) 2016 VMware, Inc. All Rights Reserved.
// This software is released under MIT license.
// The full license information can be found in LICENSE in the root directory of this project.
app-requests-modal {
z-index: 10000;
}
header.app-header {
background: #314351 !important;
color: #fff;
}
.logo img.without-text {
width: 30px;
}
.logo img.with-text {
width: 210px;
}
.header-hamburger-trigger {
display: block;
background: transparent;
border: 0;
margin-left: 10px;
}
.demo-expired-notice {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: 0;
height: 100vh !important;
width: 100vw !important;
z-index: 105;
background: rgba(33, 33, 33, .5);
.expired-details {
flex-direction: column;
align-items: center;
padding: 30px;
z-index: 110;
background: #314351;
.expired-notice {
color: #e0e0e0;
font-size: 16px;
.mailto {
color: #8dc53e;
}
}
}
}
.main-container .update-key {
display: flex;
align-items: center;
color: white;
padding: 0px 10px;
background: #00000026;
}
.alert-icon-wrapper {
margin-top: 0 !important;
}
.nav-text {
margin-right: 20px;
}
.sidebar-toggle {
display: flex;
height: 100%;
align-items: center;
padding-left: 10px;
clr-icon {
cursor: pointer;
width: 30px;
height: 30px;
}
}
header {
.header-actions {
.dropdown {
position: unset; //without it, when opening user dropdown scrollbar was displaying without reason
}
}
.nav
.nav-link {
color: #fafafa;
opacity: .9;
line-height: 1.45rem;
}
.nav .nav-link:hover {
box-shadow: inset 0 -3px 0 transparent;
transition: box-shadow .2s ease-in;
}
.nav
.nav-link:hover {
color: #fafafa;
opacity: 1;
}
.nav .nav-link.active {
background: #61717D;
opacity: 1;
box-shadow: inset 0 -3px transparent;
// padding: 0 1rem 0 1rem;
}
.nav .nav-item {
margin-right: 1rem;
}
}
.notf {
background: #16a57a;
color: #fffcfc;
font-size: 12px;
}
.btn.btn-success {
border-color: #62a420;
background-color: #16a57a!important;
color: #fff;
}
.btn.btn-success:hover {
background-color: #2add39;
color: #fff;
}
.toggle-switch input[type=checkbox]:checked+label:before {
border-color: #61717D;
background-color: #61717D;
transition: .15s ease-in;
transition-property: border-color,background-color;
}
.main-container {
min-height: 100vh !important;
}
.main-container .content-container .content-area {
padding: 0rem 1rem 1rem 1rem;
}
.content-container {
z-index: 0!important;
}
.navBarResp {
display: flex;
justify-content: center;
background: #495A67;
color: #fff;
}
@media screen and (max-width: 768px) {
.navBarResp {
display: flex;
justify-content: flex-start;
background: #495A67;
color: #fff;
}
.main-container .sub-nav.clr-nav-level-1 .nav .nav-link, .main-container .sub-nav.clr-nav-level-2 .nav .nav-link, .main-container .subnav.clr-nav-level-1 .nav .nav-link, .main-container .subnav.clr-nav-level-2 .nav .nav-link {
padding: 0 .5rem 0 1rem;
width: 100%;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
border-radius: .125rem 0 0 .125rem;
color: #95c84b;
}
.card-block, .card-footer {
padding: 10px 0px 0px 0px;
}
.main-container[_ngcontent-c0] .content-container[_ngcontent-c0] .content-area[_ngcontent-c0] {
padding: 0rem 0rem 0rem 0rem;
}
}
::ng-deep {
.htInvalid {
background: black!important;
}
@media screen and (max-width:480px) {
h2 {
font-size: .7rem!important;
}
h3 {
font-size: .7rem;
}
}
.nav-link {
padding: 0rem 1rem 0rem 1rem;
}
.btn-primary .btn, .btn.btn-primary {
border-color: #314351;
background-color: #314351;
color: #fff;
}
.btn {
cursor: pointer;
display: inline-block;
-webkit-appearance: none!important;
border-radius: .125rem;
border: 1px solid;
min-width: 3rem;
max-width: 15rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
text-align: center;
text-transform: uppercase;
vertical-align: middle;
line-height: 1.5rem;
letter-spacing: .12em;
font-size: .5rem;
font-weight: 500;
height: 1.5rem;
padding: 0 .5rem;
border-color: #314351;
background-color: transparent;
color: #314351;
}
.btn.btn-outline {
border-color: #314351;
background-color: transparent;
color: #314351;
}
.btn.btn-outline:hover {
border-color: #314351;
background-color: #495A67;
color: #fff;
}
.btn.btn-success-outline:hover {
background-color: #5ea71f;
color: #fff7f7;
border-color: #9a9696;
}
// .btn.btn-success-outline {
// border-color: #266900;
// background-color: transparent;
// color: #318700;
// }
// .wtSpreader {
// }
.htMobileEditorContainer .inputs textarea {
font-size: 13pt;
border: 2px solid #485967;
border-radius: 4px;
-webkit-appearance: none;
box-shadow: none;
position: absolute;
left: 14px;
right: 0px;
top: 0;
bottom: 0;
padding: 7pt;
width: 290px;
}
.htMobileEditorContainer .positionControls {
width: 333px;
position: absolute;
right: 5pt;
top: 50px;
bottom: 0;
display: flex;
justify-content: center;
}
.htMobileEditorContainer.active {
display: block;
height: 120px;
width: 350px;
}
.handsontable {
background-color: #ffffff;
// border: 1px solid #ccc;
border-radius: 3px;
}
.handsontable th {
background-color: #fafafa;
}
/* Left and right */
.ht_clone_left th {
border-right: 1px solid #ccc;
border-left: 1px solid #ccc;
}
/* Column headers */
.ht_clone_top th {
border-top: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
}
.ht_clone_top_left_corner th {
border-right: 1px solid #ccc;
}
.ht_master tr:nth-of-type(odd) > td {
background-color: #f3f3f3;
border: 1px solid rgb(197, 197, 197);
border-bottom: 1px solid rgb(236, 235, 235);
// padding: 1px 1px;
}
.ht_master tr:nth-of-type(even) > td {
background-color: white;
border: 1px solid rgb(197, 197, 197);
border-bottom: 1px solid rgb(236, 235, 235);
// padding: 1px 1px;
}
.wtBorder {
background-color: #495A67!important;
}
.handsontable .handsontable.ht_clone_top .wtHider {
padding: 0 0 0px 0!important;
margin: 0px;
border-bottom: 3px solid #d6d3d3;
}
.content-container {
background: #F5F6FF;
}
.card {
box-shadow: 0 0.125rem 0 0 #d7d7d7;
border-radius: .0rem;
border: 1px solid transparent;
// min-height: calc(100vh - 150px);
}
.datagrid-compact, .datagrid-history{
.datagrid {
border-collapse: separate;
border: 1px solid transparent;
border-radius: .125rem;
background-color: #fff;
color: #565656;
margin: 0;
margin-top: 1rem;
max-width: 100%;
width: 100%;
padding: 15px 15px 50px 15px;
}
.datagrid-foot {
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
height: 1.5rem;
padding: 0 .5rem;
line-height: calc(1.5rem - 3px);
font-size: .45833rem;
background-color: #fff;
border-top: 1px solid #ccc;
border-radius: 0px;
// border-radius: 0 0 .125rem .125rem;
}
.datagrid-footer {
position: absolute;
right: 15px;
top: 2px;
}
.datagrid .datagrid-head {
background-color: #fff;
border-bottom: 1px solid #ccc;
}
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
margin-top: .083333rem;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
background: #f5f6ff;
padding: .5rem 0;
border: 1px solid #ccc;
box-shadow: 0 1px 0.125rem hsla(0,0%,45%,.25);
min-width: 5rem;
max-width: 15rem;
border-radius: .125rem;
visibility: hidden;
z-index: 1000;
}
.table {
border-collapse: separate;
border: 1px solid transparent;
border-radius: 0px;
background-color: #fff;
color: #565656;
margin: 0;
margin-top: 1rem;
max-width: 100%;
width: 100%;
}
.table th {
font-size: .45833rem;
font-weight: 600;
letter-spacing: .03em;
background-color: #fff;
vertical-align: bottom;
border-bottom: 1px solid #ccc;
text-transform: uppercase;
}
.modal-header {
border-bottom: 2px solid #e4e4e4;
padding: 0 0 .5rem 0;
margin-bottom: 1rem;
}
.main-container .content-container {
min-height: 0px;
position: relative;
}
}
.app-loading {
.loading-logo {
max-width: 400px;
width: 100%;
}
}

View File

@ -1,9 +1,4 @@
import { import { ChangeDetectorRef, Component, ElementRef } from '@angular/core'
ChangeDetectorRef,
Component,
ElementRef,
ViewEncapsulation
} from '@angular/core'
import { Router } from '@angular/router' import { Router } from '@angular/router'
import { VERSION } from '../environments/version' import { VERSION } from '../environments/version'
import { ActivatedRoute } from '@angular/router' import { ActivatedRoute } from '@angular/router'
@ -18,31 +13,11 @@ import { InfoModal } from './models/InfoModal'
import { DcAdapterSettings } from './models/DcAdapterSettings' import { DcAdapterSettings } from './models/DcAdapterSettings'
import { AppStoreService } from './services/app-store.service' import { AppStoreService } from './services/app-store.service'
import { LicenceService } from './services/licence.service' import { LicenceService } from './services/licence.service'
import '@cds/core/icon/register.js'
import {
ClarityIcons,
exclamationTriangleIcon,
moonIcon,
processOnVmIcon,
sunIcon,
tableIcon,
trashIcon
} from '@cds/core/icon'
ClarityIcons.addIcons(
moonIcon,
sunIcon,
exclamationTriangleIcon,
tableIcon,
trashIcon,
processOnVmIcon
)
@Component({ @Component({
selector: 'my-app', selector: 'my-app',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'], styleUrls: ['./app.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class AppComponent { export class AppComponent {
private dcAdapterSettings: DcAdapterSettings | undefined private dcAdapterSettings: DcAdapterSettings | undefined

View File

@ -20,10 +20,10 @@ import { UsernavRouteComponent } from './routes/usernav-route/usernav-route.comp
import { AppService } from './services/app.service' import { AppService } from './services/app.service'
import { InfoModalComponent } from './shared/abort-modal/info-modal.component' import { InfoModalComponent } from './shared/abort-modal/info-modal.component'
import { RequestsModalComponent } from './shared/requests-modal/requests-modal.component' import { RequestsModalComponent } from './shared/requests-modal/requests-modal.component'
import { HomeModule } from './home/home.module'
import { DirectivesModule } from './directives/directives.module' import { DirectivesModule } from './directives/directives.module'
import { ViyaApiExplorerComponent } from './viya-api-explorer/viya-api-explorer.component' import { ViyaApiExplorerComponent } from './viya-api-explorer/viya-api-explorer.component'
import { NgxJsonViewerModule } from 'ngx-json-viewer' import { NgxJsonViewerModule } from 'ngx-json-viewer'
import { AppSettingsService } from './services/app-settings.service'
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -46,11 +46,12 @@ import { AppSettingsService } from './services/app-settings.service'
SharedModule, SharedModule,
ClarityModule, ClarityModule,
AppSharedModule, AppSharedModule,
HomeModule,
PipesModule, PipesModule,
DirectivesModule, DirectivesModule,
NgxJsonViewerModule NgxJsonViewerModule
], ],
providers: [AppService, SasStoreService, LicensingGuard, AppSettingsService], providers: [AppService, SasStoreService, LicensingGuard],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule {} export class AppModule {}

View File

@ -4,19 +4,19 @@
* The full license information can be found in LICENSE in the root directory of this project. * The full license information can be found in LICENSE in the root directory of this project.
*/ */
import { ModuleWithProviders } from '@angular/core' import { ModuleWithProviders } from '@angular/core'
import { RouterModule, Routes } from '@angular/router' import { Routes, RouterModule } from '@angular/router'
import { HomeComponent } from './home/home.component'
import { NotFoundComponent } from './not-found/not-found.component' import { NotFoundComponent } from './not-found/not-found.component'
import { DeployModule } from './deploy/deploy.module'
import { EditorModule } from './editor/editor.module'
import { HomeModule } from './home/home.module'
import { LicensingModule } from './licensing/licensing.module'
import { ReviewModule } from './review/review.module'
import { ReviewRouteComponent } from './routes/review-route/review-route.component' import { ReviewRouteComponent } from './routes/review-route/review-route.component'
import { StageModule } from './stage/stage.module' import { StageModule } from './stage/stage.module'
import { SystemModule } from './system/system.module' import { EditorModule } from './editor/editor.module'
import { ViewerModule } from './viewer/viewer.module' import { ViewerModule } from './viewer/viewer.module'
import { ReviewModule } from './review/review.module'
import { DeployModule } from './deploy/deploy.module'
import { LicensingModule } from './licensing/licensing.module'
import { SystemModule } from './system/system.module'
/** /**
* Defining routes * Defining routes
@ -45,10 +45,7 @@ export const ROUTES: Routes = [
path: 'licensing', path: 'licensing',
loadChildren: () => LicensingModule loadChildren: () => LicensingModule
}, },
{ { path: 'home', component: HomeComponent },
path: 'home',
loadChildren: () => HomeModule
},
{ {
/** /**
* Load editor module with subroutes * Load editor module with subroutes

View File

@ -5,7 +5,7 @@
<div class="card-header">Terms and Conditions</div> <div class="card-header">Terms and Conditions</div>
<div class="card-block"> <div class="card-block">
<div class="card-text"> <div class="card-text">
<p class="mt-0"> <p>
The Demo version of Data Controller is free for EVALUATION purposes The Demo version of Data Controller is free for EVALUATION purposes
only. Before proceeding with configuration, please confirm that you only. Before proceeding with configuration, please confirm that you
have read, understood, and agreed to the have read, understood, and agreed to the

View File

@ -0,0 +1,50 @@
.card {
margin-top: 0;
}
.btn {
margin-top: 10px;
}
.log-wrapper {
width: 100%;
background: #f0f0f0;
border: 1px solid #c9c9c9;
padding: 10px;
overflow: auto;
white-space: pre-wrap;
}
#contexts-btn {
padding: 0;
min-width: 30px;
margin-left: 10px;
height: 30px;
display: inline-flex;
justify-content: center;
align-items: center;
padding-top: 3px;
}
.validation-bar {
display: flex;
margin-top: 20px;
align-items: center;
clr-icon {
margin-right: 5px;
}
}
.autodeploy-section {
padding: 0px 15px;
.clr-checkbox-wrapper {
margin: 20px 0 20px 0;
}
.btn-autodeploy {
display: block;
margin: 15px 0 15px 0;
}
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
import { SasService } from '../services/sas.service' import { SasService } from '../services/sas.service'
import { SASjsConfig } from '@sasjs/adapter' import { SASjsConfig } from '@sasjs/adapter'
import { Router } from '@angular/router' import { Router } from '@angular/router'
@ -13,8 +13,7 @@ import { DcAdapterSettings } from '../models/DcAdapterSettings'
styleUrls: ['./deploy.component.scss'], styleUrls: ['./deploy.component.scss'],
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class DeployComponent implements OnInit { export class DeployComponent implements OnInit {
public step: number = 0 public step: number = 0
@ -57,6 +56,25 @@ export class DeployComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
if (this.sasJsConfig.serverType === ServerType.SasViya) {
fetch('sasbuild/viya.json')
.then((res) => res.text())
.then((res) => {
let initJsonFile: any = null
try {
initJsonFile = JSON.parse(res)
} catch (err) {
console.error(err)
}
if (initJsonFile) {
this.jsonFile = initJsonFile
this.loggerService.log(this.jsonFile)
}
})
}
this.setDeployDefaults() this.setDeployDefaults()
} }

View File

@ -9,17 +9,14 @@
<p class="m-0 align-self-start">Done</p> <p class="m-0 align-self-start">Done</p>
<hr class="w-100" /> <hr class="w-100" />
<div <div class="deploy-status-row">
*ngIf="autoDeployStatus.deployServicePack !== null"
class="deploy-status-row"
>
<clr-icon <clr-icon
*ngIf="autoDeployStatus.deployServicePack === true" *ngIf="autoDeployStatus.deployServicePack"
class="deploy-success" class="deploy-success"
shape="success-standard" shape="success-standard"
></clr-icon> ></clr-icon>
<clr-icon <clr-icon
*ngIf="!autoDeployStatus.deployServicePack === false" *ngIf="!autoDeployStatus.deployServicePack"
class="deploy-error" class="deploy-error"
shape="times-circle" shape="times-circle"
></clr-icon> ></clr-icon>
@ -55,7 +52,7 @@
class="deploy-error" class="deploy-error"
shape="times-circle" shape="times-circle"
></clr-icon> ></clr-icon>
LAUNCH LAUNCH / CONFIGURE
</button> </button>
<button <button
@ -97,36 +94,20 @@
</div> </div>
<label for="dcloc" class="mt-20 clr-control-label">DC Loc</label> <label for="dcloc" class="mt-20 clr-control-label">DC Loc</label>
<div class="mb-10 clr-control-container dc-loc-input-wrapper"> <div class="mb-10 clr-control-container">
<div class="clr-input-wrapper"> <div class="clr-input-wrapper">
<input clrInput name="dcloc" [(ngModel)]="dcPath" /> <p class="mt-0">{{ dcPath }}</p>
</div> </div>
</div> </div>
<label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label> <label for="dcloc" class="mt-20 clr-control-label">SAS Admin group</label>
<div class="mb-10 clr-control-container"> <div class="mb-10 clr-control-container">
<div class="clr-input-wrapper"> <div class="clr-input-wrapper">
<select <p class="mt-0">{{ selectedAdminGroup }}</p>
*ngIf="!adminGroupsLoading"
clrSelect
name="options"
[(ngModel)]="selectedAdminGroup"
>
<option *ngFor="let adminGroup of adminGroups" [value]="adminGroup.id">
{{ adminGroup.name }}
</option>
</select>
<clr-spinner
clrInline
class="spinner-sm"
*ngIf="adminGroupsLoading"
></clr-spinner>
</div> </div>
</div> </div>
<!-- Keeping this for a reference in case future VIYA changes and starts allowing separate backend and frontend) --> <clr-checkbox-wrapper>
<!-- <clr-checkbox-wrapper>
<input <input
clrCheckbox clrCheckbox
[(ngModel)]="recreateDatabase" [(ngModel)]="recreateDatabase"
@ -135,28 +116,19 @@
checked checked
/> />
<label>Recreate database</label> <label>Recreate database</label>
</clr-checkbox-wrapper> --> </clr-checkbox-wrapper>
<hr /> <hr />
<button <button
(click)="runAutoDeploy()"
class="btn-autodeploy btn btn-primary d-inline-block mr-10"
>
Deploy
</button>
<!-- Keeping this for a reference in case future VIYA changes and starts allowing separate backend and frontend) -->
<!-- <button
(click)="executeJson()" (click)="executeJson()"
class="btn-autodeploy btn btn-primary d-inline-block mr-10" class="btn-autodeploy btn btn-primary d-inline-block mr-10"
[disabled]="!jsonFile" [disabled]="!jsonFile"
> >
Deploy {{ !jsonFile ? '(json file is not available)' : '' }} Deploy {{ !jsonFile ? '(json file is not available)' : '' }}
</button> --> </button>
<!-- <button <button
(click)="uploadJsonAuto.click()" (click)="uploadJsonAuto.click()"
class="btn-autodeploy btn btn-primary d-inline-block mr-10" class="btn-autodeploy btn btn-primary d-inline-block mr-10"
> >
@ -168,7 +140,7 @@
hidden hidden
(click)="clearUploadInput($event)" (click)="clearUploadInput($event)"
(change)="onJsonFileChange($event)" (change)="onJsonFileChange($event)"
/> --> />
<clr-modal [(clrModalOpen)]="recreateDatabaseModal" [clrModalClosable]="false"> <clr-modal [(clrModalOpen)]="recreateDatabaseModal" [clrModalClosable]="false">
<h3 class="modal-title">Warning</h3> <h3 class="modal-title">Warning</h3>

View File

@ -0,0 +1,61 @@
.auto-deploy {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 100;
}
.spinner-box {
width: 400px;
padding: 20px;
border-radius: 3px;
background: #fff;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
box-shadow: 1px 1px 8px 0px #00000082;
.buttons {
display: flex;
justify-content: space-between;
width: 100%;
}
}
.deploy-status-row {
display: flex;
align-items: center;
align-self: flex-start;
p {
margin: 0 0 0 10px;
}
}
.deploy-success {
color: #6ECF44;
}
.deploy-error {
color: #E74C3C;
// width: 20px;
// height: 20px;
}
.deploy-undeterminated {
color: #cacaca;
}
hr {
border: 0;
border-bottom: 1px solid #00000045;
}

View File

@ -1,29 +1,15 @@
import { import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
Component,
EventEmitter,
Input,
OnInit,
Output,
ViewEncapsulation
} from '@angular/core'
import SASjs, { SASjsConfig } from '@sasjs/adapter' import SASjs, { SASjsConfig } from '@sasjs/adapter'
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
import { DeployService } from 'src/app/services/deploy.service' import { DeployService } from 'src/app/services/deploy.service'
import { EventService } from 'src/app/services/event.service' import { EventService } from 'src/app/services/event.service'
import { LoggerService } from 'src/app/services/logger.service' import { LoggerService } from 'src/app/services/logger.service'
import { SasViyaService } from 'src/app/services/sas-viya.service'
import { SasService } from 'src/app/services/sas.service' import { SasService } from 'src/app/services/sas.service'
import { ViyaApiCurrentUser } from 'src/app/viya-api-explorer/models/viya-api-current-user.model'
import {
Item,
ViyaApiIdentities
} from 'src/app/viya-api-explorer/models/viya-api-identities.model'
@Component({ @Component({
selector: 'app-automatic-deploy', selector: 'app-automatic-deploy',
templateUrl: './automatic.component.html', templateUrl: './automatic.component.html',
styleUrls: ['./automatic.component.scss'], styleUrls: ['./automatic.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class AutomaticComponent implements OnInit { export class AutomaticComponent implements OnInit {
@Input() sasJs!: SASjs @Input() sasJs!: SASjs
@ -42,16 +28,8 @@ export class AutomaticComponent implements OnInit {
public recreateDatabaseModal: boolean = false public recreateDatabaseModal: boolean = false
public isSubmittingJson: boolean = false public isSubmittingJson: boolean = false
public isJsonSubmitted: boolean = false public isJsonSubmitted: boolean = false
/** public recreateDatabase: boolean = false
* Default was `false` when deploy was done with frontend and backend separately.
* Now we are using only streaming app, so we always want to recreate database (makedata)
*/
public recreateDatabase: boolean = true
public createDatabaseLoading: boolean = false public createDatabaseLoading: boolean = false
public adminGroupsLoading: boolean = false
public currentUserInfoLoading: boolean = false
public adminGroups: { id: string; name: string }[] = []
public currentUserInfo: ViyaApiCurrentUser | null = null
/** autoDeployStatus /** autoDeployStatus
* This object presents the status for two steps that we have for deploy. * This object presents the status for two steps that we have for deploy.
@ -72,48 +50,10 @@ export class AutomaticComponent implements OnInit {
private eventService: EventService, private eventService: EventService,
private deployService: DeployService, private deployService: DeployService,
private sasService: SasService, private sasService: SasService,
private sasViyaService: SasViyaService,
private loggerService: LoggerService private loggerService: LoggerService
) {} ) {}
ngOnInit(): void { ngOnInit(): void {}
this.getAdminGroups()
this.getCurrentUser()
}
public async getCurrentUser() {
this.currentUserInfoLoading = true
this.sasViyaService
.getCurrentUser()
.subscribe((res: ViyaApiCurrentUser) => {
this.currentUserInfoLoading = false
this.currentUserInfo = res
this.dcPath = `/export/viya/homes/${res.id}`
})
}
public async getAdminGroups() {
this.adminGroupsLoading = true
this.sasViyaService.getAdminGroups().subscribe((res: ViyaApiIdentities) => {
this.adminGroupsLoading = false
// Map admin groups with only needed fields
this.adminGroups = res.items.map((item: Item) => {
return {
id: item.id,
name: item.name
}
})
}),
(err: any) => {
this.adminGroupsLoading = false
this.loggerService.error('Error while getting admin groups', err)
this.eventService.showAbortModal('admin groups', err)
}
}
/** /**
* Executes sas.json file to deploy the backend * Executes sas.json file to deploy the backend
@ -123,6 +63,7 @@ export class AutomaticComponent implements OnInit {
* to create database if checkbox is toggled on * to create database if checkbox is toggled on
*/ */
public async executeJson() { public async executeJson() {
this.autodeploying = true
this.isSubmittingJson = true this.isSubmittingJson = true
try { try {
@ -157,14 +98,6 @@ export class AutomaticComponent implements OnInit {
} }
this.isSubmittingJson = false this.isSubmittingJson = false
}
public async runAutoDeploy(executeJson: boolean = false) {
this.autodeploying = true
if (executeJson) {
this.executeJson()
}
if (this.recreateDatabase) { if (this.recreateDatabase) {
this.createDatabase() this.createDatabase()
@ -192,7 +125,7 @@ export class AutomaticComponent implements OnInit {
* contextName: null is the MUST field for it. * contextName: null is the MUST field for it.
*/ */
let overrideConfig = { let overrideConfig = {
useComputeApi: null, useComputeApi: false,
contextName: this.sasJsConfig.contextName, contextName: this.sasJsConfig.contextName,
debug: true debug: true
} }
@ -215,21 +148,8 @@ export class AutomaticComponent implements OnInit {
} else { } else {
this.autoDeployStatus.runMakeData = false this.autoDeployStatus.runMakeData = false
} }
if (typeof res.sasjsAbort !== 'undefined') {
const abortRes = res
const abortMsg = abortRes.sasjsAbort[0].MSG
const macMsg = abortRes.sasjsAbort[0].MAC
this.eventService.showAbortModal('makedata', abortMsg, {
SYSWARNINGTEXT: abortRes.SYSWARNINGTEXT,
SYSERRORTEXT: abortRes.SYSERRORTEXT,
MAC: macMsg
})
}
}) })
.catch((err: any) => { .catch((err: any) => {
this.eventService.showAbortModal('makedata', JSON.stringify(err))
this.autoDeployStatus.runMakeData = false this.autoDeployStatus.runMakeData = false
this.autodeployDone = true this.autodeployDone = true

View File

@ -0,0 +1,4 @@
.clear-memory-button {
right: 10px;
top: 2px;
}

View File

@ -1,14 +1,6 @@
import { import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core'
Component,
Input,
OnInit,
Output,
EventEmitter,
ViewEncapsulation
} from '@angular/core'
import SASjs, { SASjsConfig } from '@sasjs/adapter' import SASjs, { SASjsConfig } from '@sasjs/adapter'
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
import { RequestWrapperResponse } from 'src/app/models/request-wrapper/RequestWrapperResponse'
import { DeployService } from 'src/app/services/deploy.service' import { DeployService } from 'src/app/services/deploy.service'
import { EventService } from 'src/app/services/event.service' import { EventService } from 'src/app/services/event.service'
import { LoggerService } from 'src/app/services/logger.service' import { LoggerService } from 'src/app/services/logger.service'
@ -17,8 +9,7 @@ import { SasService } from 'src/app/services/sas.service'
@Component({ @Component({
selector: 'app-manual-deploy', selector: 'app-manual-deploy',
templateUrl: './manual.component.html', templateUrl: './manual.component.html',
styleUrls: ['./manual.component.scss'], styleUrls: ['./manual.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class ManualComponent implements OnInit { export class ManualComponent implements OnInit {
@Input() sasJs!: SASjs @Input() sasJs!: SASjs
@ -274,7 +265,7 @@ export class ManualComponent implements OnInit {
* contextName: null is the MUST field for it. * contextName: null is the MUST field for it.
*/ */
let overrideConfig = { let overrideConfig = {
useComputeApi: null, useComputeApi: false,
contextName: this.sasJsConfig.contextName, contextName: this.sasJsConfig.contextName,
debug: true debug: true
} }
@ -312,10 +303,10 @@ export class ManualComponent implements OnInit {
this.sasService this.sasService
.request('public/startupservice', null) .request('public/startupservice', null)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.loggerService.log(res.adapterResponse) this.loggerService.log(res)
if (res.adapterResponse.saslibs) { if (res.saslibs) {
this.validationState = 'success' this.validationState = 'success'
} else { } else {
this.validationState = 'error' this.validationState = 'error'

View File

@ -10,13 +10,11 @@
</p> </p>
<p class="m-0 mt-10"> <p class="m-0 mt-10">
Please specify a physical directory (on the Please specify a physical directory below, to which user
<strong> {{ SYSHOSTNAME }}</strong> <strong>{{ SYSUSERID }}</strong> can write, on behalf of Data Controller:
compute server) below, to which user
<strong>{{ SYSUSERID }}</strong> can write, on behalf of Data Controller.
</p> </p>
<label class="mt-20 clr-control-label">DC Staging Directory</label> <label class="mt-20 clr-control-label">DC Directory</label>
<div class="mb-10 clr-control-container"> <div class="mb-10 clr-control-container">
<div class="clr-input-wrapper"> <div class="clr-input-wrapper">
<input <input

View File

@ -0,0 +1,23 @@
.clr-control-container {
width: 50vw;
}
.clr-input-wrapper {
width: 100%;
input {
width: 100%;
}
}
.thinProgress {
left: 0px;
right: 0;
width: unset;
height: 1px;
margin-top: 0 !important;
&::after {
top: 0;
}
}

View File

@ -1,16 +1,8 @@
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
Component,
EventEmitter,
Input,
OnInit,
Output,
ViewEncapsulation
} from '@angular/core'
import SASjs, { SASjsConfig } from '@sasjs/adapter' import SASjs, { SASjsConfig } from '@sasjs/adapter'
import { ServerType } from '@sasjs/utils/types/serverType' import { ServerType } from '@sasjs/utils/types/serverType'
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings' import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
import { RequestWrapperResponse } from 'src/app/models/request-wrapper/RequestWrapperResponse'
import { SASGroup } from 'src/app/models/sas/public-getgroups.model' import { SASGroup } from 'src/app/models/sas/public-getgroups.model'
import { SASjsApiServerInfo } from 'src/app/models/sasjs-api/SASjsApiServerInfo.model' import { SASjsApiServerInfo } from 'src/app/models/sasjs-api/SASjsApiServerInfo.model'
import { SasService } from 'src/app/services/sas.service' import { SasService } from 'src/app/services/sas.service'
@ -19,8 +11,7 @@ import { SasjsService } from 'src/app/services/sasjs.service'
@Component({ @Component({
selector: 'app-sasjs-configurator', selector: 'app-sasjs-configurator',
templateUrl: './sasjs-configurator.component.html', templateUrl: './sasjs-configurator.component.html',
styleUrls: ['./sasjs-configurator.component.scss'], styleUrls: ['./sasjs-configurator.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class SasjsConfiguratorComponent implements OnInit { export class SasjsConfiguratorComponent implements OnInit {
@Input() sasJs!: SASjs @Input() sasJs!: SASjs
@ -77,11 +68,11 @@ export class SasjsConfiguratorComponent implements OnInit {
this.loading = true this.loading = true
this.sasService.request('usernav/usergroupsbymember', null).then( this.sasService.request('usernav/usergroupsbymember', null).then(
(res: RequestWrapperResponse) => { (res: any) => {
this.METAPERSON = res.adapterResponse.MF_GETUSER this.METAPERSON = res.MF_GETUSER
this.SYSUSERID = res.adapterResponse.SYSUSERID this.SYSUSERID = res.SYSUSERID
this.SYSHOSTNAME = res.adapterResponse.SYSHOSTNAME this.SYSHOSTNAME = res.SYSHOSTNAME
this.SYSVLONG = res.adapterResponse.SYSVLONG this.SYSVLONG = res.SYSVLONG
/* /*
We would like to present a default DCPATH (deployment path) to the We would like to present a default DCPATH (deployment path) to the
@ -97,14 +88,12 @@ export class SasjsConfiguratorComponent implements OnInit {
*/ */
this.dcDirectory = this.dcDirectory =
this.tmpDirectories[ this.tmpDirectories[
['L', 'H', 'A', 'S'].includes( ['L', 'H', 'A', 'S'].includes(res.SYSSCPL.substring(0, 1))
res.adapterResponse.SYSSCPL.substring(0, 1)
)
? 'linux' ? 'linux'
: 'windows' : 'windows'
] ]
this.dcAdminGroupList = res.adapterResponse.groups this.dcAdminGroupList = res.groups
this.dcAdminGroup = this.dcAdminGroupList[0].GROUPNAME this.dcAdminGroup = this.dcAdminGroupList[0].GROUPNAME
this.loading = false this.loading = false

View File

@ -4,23 +4,20 @@ import { NgVarDirective } from './ng-var.directive'
import { DragNdropDirective } from './drag-ndrop.directive' import { DragNdropDirective } from './drag-ndrop.directive'
import { FileDropDirective } from './file-drop.directive' import { FileDropDirective } from './file-drop.directive'
import { FileSelectDirective } from './file-select.directive' import { FileSelectDirective } from './file-select.directive'
import { StealFocusDirective } from './steal-focus.directive'
@NgModule({ @NgModule({
declarations: [ declarations: [
NgVarDirective, NgVarDirective,
DragNdropDirective, DragNdropDirective,
FileDropDirective, FileDropDirective,
FileSelectDirective, FileSelectDirective
StealFocusDirective
], ],
imports: [CommonModule], imports: [CommonModule],
exports: [ exports: [
NgVarDirective, NgVarDirective,
DragNdropDirective, DragNdropDirective,
FileDropDirective, FileDropDirective,
FileSelectDirective, FileSelectDirective
StealFocusDirective
] ]
}) })
export class DirectivesModule {} export class DirectivesModule {}

View File

@ -1,17 +0,0 @@
import { Directive, HostListener } from '@angular/core'
@Directive({
selector: '[appStealFocus]'
})
export class StealFocusDirective {
constructor() {}
/**
* For some reason newest version of Clarity v17.0.1 is stealing focus when
* clicking on the input inside of the clr-tree-view
* This is workaround
*/
@HostListener('click', ['$event']) onClick(event: any) {
event.target.focus()
}
}

View File

@ -24,8 +24,8 @@
generatedRecordUrl generatedRecordUrl
? 'copy to clipboard' ? 'copy to clipboard'
: generateEditRecordUrlLoading : generateEditRecordUrlLoading
? 'Generating url...' ? 'Generating url...'
: 'Link to this record' : 'Link to this record'
}} }}
</button> </button>
</ng-container> </ng-container>
@ -112,7 +112,7 @@
<div <div
*ngIf=" *ngIf="
['autocomplete', 'autocomplete.custom'].includes( ['autocomplete'].includes(
$any(currentRecordValidator?.getRule(col.key)?.editor) $any(currentRecordValidator?.getRule(col.key)?.editor)
) )
" "
@ -163,7 +163,7 @@
<div <div
*ngIf=" *ngIf="
['autocomplete', 'autocomplete.custom'].includes( ['autocomplete'].includes(
$any(currentRecordValidator?.getRule(col.key)?.editor) $any(currentRecordValidator?.getRule(col.key)?.editor)
) )
" "
@ -277,7 +277,7 @@
<div> <div>
<button <button
type="button" type="button"
class="btn btn-outline focusable mr-5i" class="btn btn-outline focusable"
(click)="currentRecord!.noLinkOption = false; closeRecordEdit()" (click)="currentRecord!.noLinkOption = false; closeRecordEdit()"
> >
Cancel Cancel

View File

@ -0,0 +1,241 @@
.record-edit-modal {
.column-entry {
display: flex;
justify-content: space-between;
.name-input-row {
width: 100%;
max-width: 260px;
.cell-desc {
margin-right: 30px;
margin-top: 10px;
}
}
.inputs-wrapper {
flex: 1;
display: flex;
align-items: center;
::ng-deep >*:not(.date-field):not(clr-select-container) {
flex: 1;
}
}
p {
margin-top: 0px;
}
::ng-deep {
.clr-textarea-wrapper {
margin-top: 0 !important;
}
.clr-form-control {
margin-top: 0px !important;
}
app-soft-select {
display: block;
width: 224px;
background: #fff;
border: 1px solid #999;
color: #000;
padding: calc(.25rem + 2px) .5rem;
border-radius: .125rem;
font-size: .541667rem;
margin-right: 6px;
input {
width: 100%;
border: 0;
background-color: #fff;
&:focus {
background: none;
border: 0 !important;
}
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
}
}
&:first-child p:first-child {
margin-top: 0;
}
}
.date-field {
position: relative;
display: inline-block;
textarea {
width: 230px;
}
.date-picker {
position: absolute;
right: 0;
top: 4px;
::ng-deep {
// clr-datepicker-view-manager {
// transform: unset !important;
// left: unset !important;
// right: 70px !important;
// }
.clr-input-group {
border: 0 !important;
}
}
}
}
.modal-body {
padding-bottom: 10px;
}
::ng-deep {
clr-select-container {
border: 1px solid #999;
color: #000;
border-radius: .125rem;
margin-right: 5px;
.clr-select-wrapper {
max-height: unset;
&::after {
top: 15px;
}
}
select {
height: auto;
padding: 10px;
padding-right: 20px;
border: 0 !important;
&:focus {
background: 0 0 !important;
}
&:hover {
background: transparent;
}
}
}
clr-input-container {
width: 224px;
background: #fff;
border: 1px solid #999;
color: #000;
padding: calc(.25rem + 2px) .5rem;
border-radius: .125rem;
font-size: .541667rem;
margin-right: 6px;
input {
width: 100%;
border: 0;
&:focus {
background: none;
border: 0 !important;
}
&::-webkit-outer-spin-button,
&::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
}
&.invalid-data {
border-color: red;
}
}
.modal-dialog {
width: 80vw;
}
.clr-control-container {
width: 100%;
textarea {
width: 100%;
resize: none;
border-color: #999;
&.invalid-data {
border-color: red;
outline: 0;
}
&.not-char {
font-family: "Lucida Console", Monaco, monospace;
}
}
}
.generate-record-url {
right: 40px;
top: 40px;
font-size: 12px;
}
.generate-record-url-button {
right: 25px;
top: 5px;
}
.modal-header {
padding: 0 0 1rem 0;
}
.modal-footer {
display: flex;
align-items: center;
justify-content: space-between;
// height: 65px;
.alert {
margin: 0;
}
}
}
}
.prev-next {
display: flex;
align-items: center;
p {
margin: 0;
}
button {
margin: 0px 10px;
}
}
.focusable {
&:focus {
box-shadow: 0 0 3px 0px #5aa220;
}
}
.entry-input-left-offset {
left: -30px;
}
.validation-info-alert {
width: 310px
}

View File

@ -1,12 +1,5 @@
import { KeyValue } from '@angular/common' import { KeyValue } from '@angular/common'
import { import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
Component,
EventEmitter,
Input,
OnInit,
Output,
ViewEncapsulation
} from '@angular/core'
import moment from 'moment' import moment from 'moment'
import { ValidateFilterSASResponse } from 'src/app/models/sas/validate-filter.model' import { ValidateFilterSASResponse } from 'src/app/models/sas/validate-filter.model'
import { QueryClause } from 'src/app/models/TableData' import { QueryClause } from 'src/app/models/TableData'
@ -23,8 +16,7 @@ import { EditRecordModal } from '../../models/EditRecordModal'
@Component({ @Component({
selector: 'app-edit-record', selector: 'app-edit-record',
templateUrl: './edit-record.component.html', templateUrl: './edit-record.component.html',
styleUrls: ['./edit-record.component.scss'], styleUrls: ['./edit-record.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class EditRecordComponent implements OnInit { export class EditRecordComponent implements OnInit {
@Input() currentRecord!: EditRecordModal @Input() currentRecord!: EditRecordModal

View File

@ -0,0 +1,8 @@
:host {
display: block;
}
p {
margin: 0;
text-align: center;
}

View File

@ -1,4 +1,4 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
/** /**
* Goal of this component is to recieve array of strings where every element is one state * Goal of this component is to recieve array of strings where every element is one state
@ -10,8 +10,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'
@Component({ @Component({
selector: 'app-upload-stater', selector: 'app-upload-stater',
templateUrl: './upload-stater.component.html', templateUrl: './upload-stater.component.html',
styleUrls: ['./upload-stater.component.scss'], styleUrls: ['./upload-stater.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class UploadStaterComponent implements OnInit { export class UploadStaterComponent implements OnInit {
public statesList: string[] = [] //States appended to be displayed public statesList: string[] = [] //States appended to be displayed

View File

@ -3,7 +3,7 @@
appFileDrop appFileDrop
(fileOver)="fileOverBase($event)" (fileOver)="fileOverBase($event)"
[uploader]="uploader" [uploader]="uploader"
(fileDrop)="attachFile($event, true)" (fileDrop)="getFileDesc($event, true)"
[clrModalSize]="'xl'" [clrModalSize]="'xl'"
[clrModalStaticBackdrop]="false" [clrModalStaticBackdrop]="false"
[clrModalClosable]="excelUploadState === 'Validating-DQ'" [clrModalClosable]="excelUploadState === 'Validating-DQ'"
@ -36,7 +36,7 @@
<div class="clr-row card-block mt-15 d-flex justify-content-between"> <div class="clr-row card-block mt-15 d-flex justify-content-between">
<div class="clr-col-md-auto"> <div class="clr-col-md-auto">
<div class="encoding-block"> <div class="encoding-block">
<clr-radio-container class="mt-0" clrInline> <clr-radio-container class="mt-0-i" clrInline>
<clr-radio-wrapper> <clr-radio-wrapper>
<input <input
type="radio" type="radio"
@ -81,7 +81,7 @@
type="file" type="file"
appFileSelect appFileSelect
[uploader]="uploader" [uploader]="uploader"
(change)="attachFile($event)" (change)="getFileDesc($event)"
/> />
</div> </div>
@ -92,7 +92,7 @@
<button <button
[disabled]="true" [disabled]="true"
class="btnView btn btn-sm btn-success profile-buttons w-100" class="btnView btn btn-sm btn-success profile-buttons w-100"
(click)="uploadParsedFiles()" (click)="getFile()"
> >
Upload Upload
</button> </button>
@ -164,28 +164,19 @@
<div <div
class="card-header clr-row buttonBar headerBar clr-flex-md-row clr-justify-content-center clr-justify-content-lg-end" class="card-header clr-row buttonBar headerBar clr-flex-md-row clr-justify-content-center clr-justify-content-lg-end"
> >
<div <div *ngIf="tableTrue" class="clr-col-12 clr-col-lg-4 backBtn">
*ngIf="tableTrue" <span class="btn btn-sm" [routerLink]="['/home']">
class="clr-col-12 clr-col-md-3 clr-col-lg-4 backBtn" <clr-icon shape="caret" dir="left" size="20"></clr-icon>Back to
> table selection
<span
class="btn icon-collapse btn-sm btn-icon btn-dimmed"
[routerLink]="['/home']"
>
<clr-icon shape="caret" dir="left" size="20"></clr-icon>
<span class="text">Back to table selection</span>
</span> </span>
<span <span (click)="viewboxManager()" class="btn btn-sm viewbox-open">
(click)="viewboxManager()"
class="btn icon-collapse btn-sm btn-icon btn-dimmed viewbox-open"
>
<clr-icon shape="view-cards" size="20"></clr-icon> <clr-icon shape="view-cards" size="20"></clr-icon>
<span class="text">Viewboxes</span> Viewboxes
</span> </span>
</div> </div>
<div <div
class="clr-col-12 clr-col-md-5 clr-col-lg-4 d-flex flex-column align-items-center" class="clr-col-12 clr-col-lg-4 d-flex flex-column align-items-center"
[class.clr-col-lg-12]="!tableTrue" [class.clr-col-lg-12]="!tableTrue"
> >
<h4 <h4
@ -193,43 +184,26 @@
libName: (libds?.split('.'))![0], libName: (libds?.split('.'))![0],
tableName: (libds?.split('.'))![1] tableName: (libds?.split('.'))![1]
} as libdsParsed" } as libdsParsed"
class="editor-title text-center mt-0" class="editor-title text-center mt-0-i"
> >
<clr-tooltip> <clr-icon
<clr-icon (click)="datasetInfo = true"
clrTooltipTrigger shape="info-circle"
(click)="datasetInfo = true" class="is-highlight cursor-pointer"
shape="info-circle" size="24"
aria-label="View dataset meta info" ></clr-icon>
class="is-highlight cursor-pointer"
size="24"
></clr-icon>
<clr-icon <clr-icon
*ngIf="libdsParsed.tableName.includes('-FC')" *ngIf="libdsParsed.tableName.includes('-FC')"
shape="bolt" shape="bolt"
class="color-yellow" class="color-yellow"
></clr-icon> ></clr-icon>
<span clrTooltipTrigger>
{{ libdsParsed.libName }}.<a
class="mr-10 view-table"
[routerLink]="'/view/data/' + libds!"
>{{ libdsParsed.tableName.replace('-FC', '') }}</a
>
</span>
<ng-container *ngIf="this.dsNote && this.dsNote.length > 0">
<clr-tooltip-content
clrPosition="bottom-left"
clrSize="lg"
*clrIfOpen
>
{{ this.dsNote }}
</clr-tooltip-content>
</ng-container>
</clr-tooltip>
{{ libdsParsed.libName }}.<a
class="mr-10"
[routerLink]="'/view/data/' + libds!"
>{{ libdsParsed.tableName.replace('-FC', '') }}</a
>
<ng-container *ngIf="dataSource"> <ng-container *ngIf="dataSource">
<ng-container *ngIf="!zeroFilterRows"> <ng-container *ngIf="!zeroFilterRows">
({{ dataSource.length | thousandSeparator: ',' }} ({{ dataSource.length | thousandSeparator: ',' }}
@ -241,37 +215,34 @@
</ng-container> </ng-container>
</h4> </h4>
</div> </div>
<div <div *ngIf="tableTrue" class="clr-col-12 clr-col-lg-4 btnCtrl">
*ngIf="tableTrue"
class="clr-col-12 clr-col-md-4 clr-col-lg-4 btnCtrl"
>
<ng-container *ngIf="hotTable.readOnly && !uploadPreview"> <ng-container *ngIf="hotTable.readOnly && !uploadPreview">
<button <button
type="button" type="button"
class="btnView btn icon-collapse btn-sm btn-icon btn-block btn-dimmed" class="btnView btn btn-sm btn-icon btn-block"
(click)="openQb()" (click)="openQb()"
> >
<clr-icon shape="filter"></clr-icon> <clr-icon shape="filter"></clr-icon>
<span class="text">Filter</span> <span>Filter</span>
</button> </button>
<button <button
type="button" type="button"
class="btn icon-collapse btn-sm btn-primary btn-block" class="btn btn-sm btn-primary btn-block"
(click)="editTable()" (click)="editTable()"
> >
<clr-icon shape="note"></clr-icon> <clr-icon shape="note"></clr-icon>
<span class="text">Edit</span> <span>Edit</span>
</button> </button>
<button <button
*ngIf="!columnLevelSecurityFlag" *ngIf="!columnLevelSecurityFlag"
(click)="onShowUploadModal()" (click)="onShowUploadModal()"
type="button" type="button"
class="btn icon-collapse btn-sm btn-success btn-block mr-0" class="btn btn-sm btn-success btn-block mr-0"
> >
<clr-icon shape="upload"></clr-icon> <clr-icon shape="upload"></clr-icon>
<span class="text">Upload</span> <span>Upload</span>
</button> </button>
</ng-container> </ng-container>
@ -309,7 +280,7 @@
licenceState.value.editor_rows_allowed === 1 licenceState.value.editor_rows_allowed === 1
? 'row' ? 'row'
: 'rows' : 'rows'
}}, contact support&#64;datacontroller.io</span }}, contact support@datacontroller.io</span
> >
</clr-tooltip-content> </clr-tooltip-content>
</clr-tooltip> </clr-tooltip>
@ -375,8 +346,8 @@
<ng-container *ngIf="!getdataError"> <ng-container *ngIf="!getdataError">
<span class="spinner"> Loading... </span> <span class="spinner"> Loading... </span>
<div class="mt-10"> <div>
<p cds-text="section">Loading table</p> <h3>Loading table</h3>
</div> </div>
</ng-container> </ng-container>
@ -385,8 +356,8 @@
<clr-icon shape="error-standard" class="error-icon"></clr-icon> <clr-icon shape="error-standard" class="error-icon"></clr-icon>
</span> </span>
<div class="mt-10"> <div>
<p cds-text="section">Loading table error</p> <h3>Loading table error</h3>
</div> </div>
</ng-container> </ng-container>
</div> </div>
@ -411,7 +382,6 @@
hotId="hotInstance" hotId="hotInstance"
id="hotTable" id="hotTable"
class="edit-hot" class="edit-hot"
className="htDark"
[class.hidden]="hotTable.hidden" [class.hidden]="hotTable.hidden"
[licenseKey]="hotTable.licenseKey" [licenseKey]="hotTable.licenseKey"
> >
@ -447,7 +417,7 @@
licenceState.value.editor_rows_allowed === 1 licenceState.value.editor_rows_allowed === 1
? 'row' ? 'row'
: 'rows' : 'rows'
}}, contact support&#64;datacontroller.io</span }}, contact support@datacontroller.io</span
> >
</clr-tooltip-content> </clr-tooltip-content>
</clr-tooltip> </clr-tooltip>
@ -497,18 +467,14 @@
: 'rows' : 'rows'
}} }}
will be submitted. To remove the restriction, contact will be submitted. To remove the restriction, contact
support&#64;datacontroller.io</span support@datacontroller.io</span
> >
<div *ngIf="tableTrue" class="clr-offset-md-2 clr-col-md-8"> <div *ngIf="tableTrue" class="clr-offset-md-2 clr-col-md-8">
<div class="text-area-full-width"> <div class="form-group">
<label for="formFields_8" class="mb-5 d-block" <label for="formFields_8">Message</label>
>Message</label
>
<textarea <textarea
clrTextarea
[(ngModel)]="message" [(ngModel)]="message"
[disabled]="!validationDone" [disabled]="!validationDone"
tabindex="0"
[value]=" [value]="
!validationDone !validationDone
? 'Please wait while we validate ' + ? 'Please wait while we validate ' +
@ -516,9 +482,10 @@
' cells.' ' cells.'
: '' : ''
" "
class="submit-reason" class="w-100"
type="text" type="text"
id="formFields_8" id="formFields_8"
rows="5"
></textarea> ></textarea>
</div> </div>
<!-- TODO:approvers list --> <!-- TODO:approvers list -->
@ -537,7 +504,6 @@
[disabled]="!validationDone" [disabled]="!validationDone"
type="submit" type="submit"
class="btn btn-sm btn-success-outline m-0" class="btn btn-sm btn-success-outline m-0"
tabindex="0"
(click)="saveTable(hotTable.data)" (click)="saveTable(hotTable.data)"
> >
Submit Submit
@ -546,7 +512,6 @@
id="cancelSubmitBtn" id="cancelSubmitBtn"
type="button" type="button"
class="btn btn-sm btn-outline" class="btn btn-sm btn-outline"
tabindex="0"
(click)="cancelSubmit(); submit = false; validationDone = 0" (click)="cancelSubmit(); submit = false; validationDone = 0"
> >
Cancel Cancel
@ -563,7 +528,7 @@
Due to current licence, only Due to current licence, only
{{ licenceState.value.submit_rows_limit }} rows in a file will {{ licenceState.value.submit_rows_limit }} rows in a file will
be submitted. To remove the restriction, contact be submitted. To remove the restriction, contact
support&#64;datacontroller.io support@datacontroller.io
</p> </p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
@ -577,7 +542,7 @@
<button <button
type="button" type="button"
class="btn btn-sm btn-primary" class="btn btn-sm btn-primary"
(click)="uploadParsedFiles(); submitLimitNotice = false" (click)="getFile(); submitLimitNotice = false"
> >
Submit Submit
</button> </button>
@ -865,12 +830,6 @@
</div> </div>
</clr-modal> </clr-modal>
<app-dataset-info <app-dataset-info [(open)]="datasetInfo" [dsmeta]="dsmeta"></app-dataset-info>
[(open)]="datasetInfo"
[dsmeta]="dsmeta"
[versions]="versions"
(rowClicked)="datasetInfoModalRowClicked($event)"
>
</app-dataset-info>
<app-viewboxes [(viewboxModal)]="viewboxes"></app-viewboxes> <app-viewboxes [(viewboxModal)]="viewboxes"></app-viewboxes>

View File

@ -0,0 +1,223 @@
.card {
margin-top: 0;
border: 0;
}
.buttonBar {
padding: 2px 10px 2px 10px;
align-items: center;
}
.testRed {
color: white;
background: rgba(255,0,0, 0.8) !important;
}
hot-table {
::ng-deep {
.firstColumnHeaderStyle button.changeType {
display: none;
}
.handsontable tbody th.ht__highlight, .handsontable thead th.ht__highlight {
&.primaryKeyHeaderStyle {
background: #306b00b0;
}
}
.primaryKeyHeaderStyle {
background: #306b006e;
}
th.readonlyCell {
div {
opacity: 0.4;
}
}
td.readonlyCell {
opacity: 0.5
}
}
}
.infoBar {
margin-top:14px;
background: #495967;
color: white;
text-align:center;
padding: 3px;
font-size: 16px;
height: 30px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
span {
width: 80%;
}
&:hover {
height: unset;
white-space: normal;
span {
width: unset;
}
}
}
.pkHeader {
background: #687682;
color: #fff;
margin: -1px -1px -1px -1px;
}
.headerBar {
// padding: 13px 0px 14px 0px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
background: #ffffff;
background: #f5f6fe;
}
.error-icon {
width: 30px;
height: 30px;
color: red;
}
.btnCtrl {
display:flex;
justify-content:flex-end;
}
.card-header {
border-bottom: 1px solid transparent;
}
.hidden {
visibility: hidden;
}
.my-drop-zone {
border: solid 1px lightgray;
border-radius: 10px;
background: whitesmoke;
box-shadow: inset 0px 0px 4px 2px #a7a5a52b;
height: 50vh;
}
.nv-file-over {
border: solid 2px green;
} /* Default class applied to drop zones on over */
.file-drop-text{
text-align: center;
}
.nv-file-over {
border: solid 2px green;
} /* Default class applied to drop zones on over */
.file-drop-text{
text-align: center;
}
@media screen and (max-width: 768px) {
.progresStatic {
margin-top:9px!important;
}
.progress, .progress-static {
width: calc(100% - 14px);
}
}
.hotEditor {
position: relative;
}
.excel-parsing {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
.details {
margin: 0;
position: absolute;
top: -45px;
}
}
.edit-record-spinner {
display: flex;
justify-content: center;
align-items: center;
background: rgba(255, 255, 255, 0.6);
position: absolute;
top: 0px;
bottom: 0px;
width: 100%;
z-index: 500;
}
@media screen and (max-width: 480px) {
.progresStatic {
margin-top:32px!important;
}
.card-block, .card-footer {
padding: 10px 0px 0px 0px;
}
}
.content-area {
padding: 0 0.8rem 0.8rem 0.8rem !important;
padding-top: 0;
// .card {
// min-height: calc(100vh - 160px);
// }
}
.drop-area {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
margin: 1px;
border: 2px dashed #fff;
z-index: -1;
span {
font-size: 20px;
margin-top: 20px;
color: #fff;
}
}
#submitBtn, #cancelSubmitBtn {
width: 150px;
}
// FIXME
// Let's leave it here for a reference if there
// is an issue with viewboxes/filter modal overlaying
// we will remove it if no issues found
// .filter-modal {
// z-index: 1210;
// }

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ import { EditRecordComponent } from './components/edit-record/edit-record.compon
import { UploadStaterComponent } from './components/upload-stater/upload-stater.component' import { UploadStaterComponent } from './components/upload-stater/upload-stater.component'
import { EditorRoutingModule } from './editor-routing.module' import { EditorRoutingModule } from './editor-routing.module'
import { EditorComponent } from './editor.component' import { EditorComponent } from './editor.component'
import { HomeModule } from '../home/home.module'
import { DcTreeModule } from '../shared/dc-tree/dc-tree.module' import { DcTreeModule } from '../shared/dc-tree/dc-tree.module'
import { DragDropModule } from '@angular/cdk/drag-drop' import { DragDropModule } from '@angular/cdk/drag-drop'
import { ViewboxesModule } from '../shared/viewboxes/viewboxes.module' import { ViewboxesModule } from '../shared/viewboxes/viewboxes.module'
@ -32,6 +33,7 @@ registerAllModules()
AppSharedModule, AppSharedModule,
DirectivesModule, DirectivesModule,
SharedModule, SharedModule,
HomeModule,
PipesModule, PipesModule,
DcTreeModule, DcTreeModule,
DragDropModule, DragDropModule,

View File

@ -11,11 +11,9 @@ export const errorRenderer = (
value: any, value: any,
cellProperties: any cellProperties: any
) => { ) => {
addDarkClass(td)
td.innerHTML = `${ td.innerHTML = `${
value ? value.toString() : '' value ? value.toString() : ''
} <cds-icon shape="exclamation-triangle" status="warning"></cds-icon>` } <clr-icon shape="exclamation-circle" status="warning"></clr-icon>`
return td return td
} }
@ -33,8 +31,6 @@ export const noSpinnerRenderer = (
value: any, value: any,
cellProperties: any cellProperties: any
) => { ) => {
addDarkClass(td)
td.innerHTML = value ? value : '' td.innerHTML = value ? value : ''
return td return td
@ -54,20 +50,9 @@ export const spinnerRenderer = (
value: any, value: any,
cellProperties: any cellProperties: any
) => { ) => {
addDarkClass(td)
td.innerHTML = `${ td.innerHTML = `${
value ? value.toString() : '' value ? value.toString() : ''
} <span class="spinner spinner-sm vertical-align-middle"></span>` } <span class="spinner spinner-sm vertical-align-middle"></span>`
return td return td
} }
/**
* Adds a htDark class to a TD element if not existing
*/
const addDarkClass = (td: any) => {
if (!td.classList.contains('htDark')) {
td.classList.add('htDark')
}
}

View File

@ -3,7 +3,6 @@
<clr-tree-node *ngIf="groups" class="search-node"> <clr-tree-node *ngIf="groups" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchLibTreeInput #searchLibTreeInput
placeholder="Filter by Groups" placeholder="Filter by Groups"
@ -28,7 +27,7 @@
<clr-tree-node <clr-tree-node
(click)="groupOnClick(group)" (click)="groupOnClick(group)"
*ngIf="!group['hidden']" *ngIf="!group['hidden']"
[class.active]="group.GROUPURI === groupUri" [class.table-active]="group.GROUPURI === groupUri"
> >
<p class="m-0 cursor-pointer list-padding"> <p class="m-0 cursor-pointer list-padding">
<clr-icon shape="users"></clr-icon> <clr-icon shape="users"></clr-icon>

View File

@ -0,0 +1,52 @@
.sidebar-height{
height: 100%;
}
.group-info-text{
display: inline;
font-size: 20px;
}
.group-info{
background-color: #f9f9f9;
border: 1px solid #a7a7a7;
border-radius: 3px;
box-shadow: 0px 2px 5px #dad7d7;
}
.group-info td{
text-align: center;
}
.group-data{
background-color: #f9f9f9;
border: 1px solid #a7a7a7;
border-radius: 3px;
box-shadow: 0px 2px 5px #dad7d7;
}
.group-data{
min-height: auto;
h3, h5{
text-align: center;
}
.member-table{
background-color: #f9f9f9;
width: 100%;
}
.member-table thead{
background-color: #dadada;
}
.member-table tbody{
tr:hover{
background-color: #e6e6e6;
cursor: pointer;
}
}
}
.table-container{
overflow: auto;
}
@media screen and (max-width: 768px){
.group-data{
min-height: unset !important;
}
}

View File

@ -1,12 +1,11 @@
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router' import { ActivatedRoute, Router } from '@angular/router'
import { SASjsConfig } from '@sasjs/adapter' import { SASjsConfig } from '@sasjs/adapter'
import { ServerType } from '@sasjs/utils/types/serverType' import { ServerType } from '@sasjs/utils/types/serverType'
import { HelperService } from '../services/helper.service' import { HelperService } from '../services/helper.service'
import { SasService } from '../services/sas.service' import { SasService } from '../services/sas.service'
import { globals } from '../_globals' import { globals } from '../_globals'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'
@Component({ @Component({
selector: 'app-group', selector: 'app-group',
@ -14,8 +13,7 @@ import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapper
styleUrls: ['./group.component.scss'], styleUrls: ['./group.component.scss'],
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class GroupComponent implements OnInit { export class GroupComponent implements OnInit {
public groups: Array<any> | undefined public groups: Array<any> | undefined
@ -84,13 +82,11 @@ export class GroupComponent implements OnInit {
globals.usernav.groupList = groups globals.usernav.groupList = groups
}) })
} else { } else {
this.sasService this.sasService.request('public/getgroups', null).then((res: any) => {
.request('public/getgroups', null) this.loading = false
.then((res: RequestWrapperResponse) => { this.groups = res.groups
this.loading = false globals.usernav.groupList = res.groups
this.groups = res.adapterResponse.groups })
globals.usernav.groupList = res.adapterResponse.groups
})
} }
} else { } else {
this.groups = globals.usernav.groupList this.groups = globals.usernav.groupList
@ -132,15 +128,14 @@ export class GroupComponent implements OnInit {
let data = { iwant: [{ groupid: this.paramURI }] } let data = { iwant: [{ groupid: this.paramURI }] }
this.sasService this.sasService
.request('usernav/usermembersbygroup', data) .request('usernav/usermembersbygroup', data)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.groupMembers = res.adapterResponse.sasmembers this.groupMembers = res.sasmembers
this.groupMemberCount = res.adapterResponse.sasmembers.length this.groupMemberCount = res.sasmembers.length
if (res.adapterResponse.sasmembers[0] !== undefined) { if (res.sasmembers[0] !== undefined) {
this.loading = false this.loading = false
this.groupUri = this.groupUri = res.sasmembers[0].URIMEM || this.paramURI
res.adapterResponse.sasmembers[0].URIMEM || this.paramURI this.groupName = res.sasmembers[0].GROUPNAME
this.groupName = res.adapterResponse.sasmembers[0].GROUPNAME this.groupDesc = res.sasmembers[0].GROUPDESC
this.groupDesc = res.adapterResponse.sasmembers[0].GROUPDESC
if (!this.groupName) { if (!this.groupName) {
this.groupName = this.paramURI this.groupName = this.paramURI
@ -207,13 +202,13 @@ export class GroupComponent implements OnInit {
this.sasService this.sasService
.request('usernav/usermembersbygroup', data) .request('usernav/usermembersbygroup', data)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.loading = false this.loading = false
this.groupUri = group.GROUPURI this.groupUri = group.GROUPURI
this.groupName = group.GROUPNAME this.groupName = group.GROUPNAME
this.groupDesc = group.GROUPDESC this.groupDesc = group.GROUPDESC
this.groupMembers = res.adapterResponse.sasmembers this.groupMembers = res.sasmembers
this.groupMemberCount = res.adapterResponse.sasmembers.length this.groupMemberCount = res.sasmembers.length
}) })
} }
} }

View File

@ -1,25 +0,0 @@
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { HomeRouteComponent } from '../routes/home-route/home-route.component'
import { HomeComponent } from './home.component'
import { XLMapModule } from '../xlmap/xlmap.module'
import { MultiDatasetModule } from '../multi-dataset/multi-dataset.module'
const routes: Routes = [
{
path: '',
component: HomeRouteComponent,
children: [
{ path: '', pathMatch: 'full', redirectTo: 'tables' },
{ path: 'tables', component: HomeComponent },
{ path: 'excel-maps', loadChildren: () => XLMapModule },
{ path: 'multi-load', loadChildren: () => MultiDatasetModule }
]
}
]
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomeRoutingModule {}

View File

@ -4,7 +4,6 @@
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
clrInput clrInput
appStealFocus
#searchLibTreeInput #searchLibTreeInput
placeholder="Libraries" placeholder="Libraries"
name="input" name="input"
@ -47,7 +46,6 @@
<clr-tree-node *ngIf="library['tables']" class="search-node"> <clr-tree-node *ngIf="library['tables']" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchTreeInput #searchTreeInput
placeholder="Tables" placeholder="Tables"
@ -87,7 +85,7 @@
(click)="!tableLocked ? onTableClick(libTable, library) : ''" (click)="!tableLocked ? onTableClick(libTable, library) : ''"
class="clr-treenode-link" class="clr-treenode-link"
[class.dc-locked-control]="tableLocked" [class.dc-locked-control]="tableLocked"
[class.active]="libTabActive(library.LIBRARYREF, libTable)" [class.table-active]="libTabActive(library.LIBRARYREF, libTable)"
> >
<ng-container [ngSwitch]="libTable.includes('-FC')"> <ng-container [ngSwitch]="libTable.includes('-FC')">
<clr-icon *ngSwitchCase="true" shape="bolt"></clr-icon> <clr-icon *ngSwitchCase="true" shape="bolt"></clr-icon>
@ -96,17 +94,15 @@
{{ libTable.replace('-FC', '') }} {{ libTable.replace('-FC', '') }}
</button> </button>
<ng-container *ngIf="tableLocked"> <clr-tooltip-content
<clr-tooltip-content clrPosition="bottom-right"
clrPosition="bottom-right" clrSize="lg"
clrSize="lg" *clrIfOpen
*clrIfOpen >
> <span *ngIf="tableLocked">
<span> To unlock all tables, contact support@datacontroller.io
To unlock all tables, contact support&#64;datacontroller.io </span>
</span> </clr-tooltip-content>
</clr-tooltip-content>
</ng-container>
</clr-tooltip> </clr-tooltip>
</clr-tree-node> </clr-tree-node>
</clr-tree-node> </clr-tree-node>
@ -123,25 +119,17 @@
</div> </div>
<div *ngIf="!loading" class="no-table-selected"> <div *ngIf="!loading" class="no-table-selected">
<img <clr-icon
src="images/select-table.png" shape="warning-standard"
class="select-table-icon" size="60"
alt="select table icon" class="is-info icon-dc-fill"
/> ></clr-icon>
<p <h3 *ngIf="treeNodeLibraries?.length! > 0" class="text-center color-gray">
*ngIf="treeNodeLibraries?.length! > 0"
class="text-center color-gray mt-10"
cds-text="section"
>
Please select a table Please select a table
</p> </h3>
<p <h3 *ngIf="treeNodeLibraries?.length! < 1" class="text-center color-gray">
*ngIf="treeNodeLibraries?.length! < 1"
class="text-center color-gray mt-10"
cds-text="section"
>
No Editable Tables Configured No Editable Tables Configured
</p> </h3>
</div> </div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,32 @@
clr-tree-node button {
white-space: nowrap;
}
.card-block {
height: 100%;
padding: 0;
}
.no-table-selected {
position: relative;
height: 100%;
}
::ng-deep {
// .badge.badge-info {
// background: #6a9235!important;
// color: #fff;
// }
clr-icon.is-blue, clr-icon.is-info {
fill: #6a9235;
}
}
.spinner-wrapper-fullpage {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}

View File

@ -3,7 +3,7 @@
* This software is released under MIT license. * This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project. * The full license information can be found in LICENSE in the root directory of this project.
*/ */
import { Component, AfterContentInit, ViewEncapsulation } from '@angular/core' import { Component, AfterContentInit } from '@angular/core'
import { Router } from '@angular/router' import { Router } from '@angular/router'
import { ActivatedRoute } from '@angular/router' import { ActivatedRoute } from '@angular/router'
import { globals } from '../_globals' import { globals } from '../_globals'
@ -18,8 +18,7 @@ import { LicenceService } from '../services/licence.service'
templateUrl: './home.component.html', templateUrl: './home.component.html',
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class HomeComponent implements AfterContentInit { export class HomeComponent implements AfterContentInit {
public treeNodeLibraries: Array<any> | null = null public treeNodeLibraries: Array<any> | null = null

View File

@ -1,18 +1,15 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core' import { NgModule } from '@angular/core'
import { FormsModule } from '@angular/forms' import { CommonModule } from '@angular/common'
import { ClarityModule } from '@clr/angular'
import { AppSharedModule } from '../app-shared.module'
import { DirectivesModule } from '../directives/directives.module'
import { HomeRouteComponent } from '../routes/home-route/home-route.component'
import { DcTreeModule } from '../shared/dc-tree/dc-tree.module'
import { HomeRoutingModule } from './home-routing.module'
import { HomeComponent } from './home.component' import { HomeComponent } from './home.component'
import { ClarityModule } from '@clr/angular'
import { FormsModule } from '@angular/forms'
import { AppSharedModule } from '../app-shared.module'
import { DcTreeModule } from '../shared/dc-tree/dc-tree.module'
import { DirectivesModule } from '../directives/directives.module'
@NgModule({ @NgModule({
declarations: [HomeComponent, HomeRouteComponent], declarations: [HomeComponent],
imports: [ imports: [
HomeRoutingModule,
FormsModule, FormsModule,
ClarityModule, ClarityModule,
AppSharedModule, AppSharedModule,

View File

@ -2,152 +2,147 @@
<div class="card-header">Licencing</div> <div class="card-header">Licencing</div>
<div [ngSwitch]="action" class="card-block"> <div [ngSwitch]="action" class="card-block">
<div class="card-text"> <ng-container *ngSwitchCase="'key'">
<ng-container *ngSwitchCase="'key'"> <p class="key-error" *ngIf="!keyError">
<p class="key-error" *ngIf="!keyError"> Licence key is invalid. We can't provide you more details at the moment
Licence key is invalid. We can't provide you more details at the
moment
</p>
<p
class="key-error"
*ngIf="keyError"
[innerHTML]="licenseErrors[keyError]"
></p>
<p *ngIf="errorDetails"><strong>Details:</strong> {{ errorDetails }}</p>
</ng-container>
<ng-container *ngSwitchCase="'limit'">
<p class="key-error">
The registered number of users reached the limit specified for your
licence. Please contact
<contact-link classes="color-green" />
or your reseller to arrange additional licences for this product.
</p>
</ng-container>
<ng-container *ngSwitchCase="'update'">
<p class="key-error">
Update the license key by uploading the licence file or by pasting a
license key and activation key in the inputs below.
</p>
</ng-container>
<p>
<strong>SYSSITE:</strong>
<span
*ngFor="let id of syssite.value; let i = index"
[class.misskey]="missmatchedKey && missmatchedKey === id"
>
{{ id }}{{ i === syssite.value?.length! - 1 ? '' : ',' }}
</span>
<a
class="tooltip tooltip-md tooltip-top-right"
(click)="copySyssite(copyIcon, copyTooltip, syssite.value || [])"
>
<clr-icon
#copyIcon
class="cursor-pointer"
shape="copy"
size="15"
></clr-icon>
<span #copyTooltip class="tooltip-content">Copy to clipboard</span>
</a>
</p> </p>
<p *ngIf="licenseKeyData && userCountLimitation" class="m-0"> <p
<strong>Allowed users:</strong> class="key-error"
{{ licenseKeyData.users_allowed }} *ngIf="keyError"
</p> [innerHTML]="licenseErrors[keyError]"
></p>
<clr-tabs> <p *ngIf="errorDetails"><strong>Details:</strong> {{ errorDetails }}</p>
<clr-tab> </ng-container>
<button clrTabLink>Upload licence</button>
<clr-tab-content> <ng-container *ngSwitchCase="'limit'">
<input <p class="key-error">
#licenceFile The registered number of users reached the limit specified for your
(change)="onFileCapture($event)" licence. Please contact
type="file" <contact-link classes="color-green" />
hidden or your reseller to arrange additional licences for this product.
/> </p>
<div </ng-container>
(click)="licenceFile.click()"
appFileDrop <ng-container *ngSwitchCase="'update'">
(fileDrop)="onFileCapture($event, true)" <p class="key-error">
class="drop-area" Update the license key by uploading the licence file or by pasting a
> license key and activation key in the inputs below.
<clr-spinner </p>
class="spinner-sm" </ng-container>
*ngIf="licenceFileLoading"
></clr-spinner> <p>
<ng-container *ngIf="!licenceFileLoading"> <strong>SYSSITE:</strong>
<div *ngIf="licencefile.filename === ''"> <span
Drop / Browse licence file *ngFor="let id of syssite.value; let i = index"
</div> [class.misskey]="missmatchedKey && missmatchedKey === id"
<div *ngIf="licencefile.filename !== ''"> >
Selected file: <strong>{{ licencefile.filename }}</strong> {{ id }}{{ i === syssite.value?.length! - 1 ? '' : ',' }}
</div> </span>
<div *ngIf="licenceFileError">
<strong>{{ licenceFileError }}</strong> <a
</div> class="tooltip tooltip-md tooltip-top-right"
</ng-container> (click)="copySyssite(copyIcon, copyTooltip, syssite.value || [])"
>
<clr-icon
#copyIcon
class="cursor-pointer"
shape="copy"
size="15"
></clr-icon>
<span #copyTooltip class="tooltip-content">Copy to clipboard</span>
</a>
</p>
<p *ngIf="licenseKeyData && userCountLimitation" class="m-0">
<strong>Allowed users:</strong>
{{ licenseKeyData.users_allowed }}
</p>
<clr-tabs>
<clr-tab>
<button clrTabLink>Upload licence</button>
<clr-tab-content>
<input
#licenceFile
(change)="onFileCapture($event)"
type="file"
hidden
/>
<div
(click)="licenceFile.click()"
appFileDrop
(fileDrop)="onFileCapture($event, true)"
class="drop-area"
>
<clr-spinner
class="spinner-sm"
*ngIf="licenceFileLoading"
></clr-spinner>
<ng-container *ngIf="!licenceFileLoading">
<div *ngIf="licencefile.filename === ''">
Drop / Browse licence file
</div>
<div *ngIf="licencefile.filename !== ''">
Selected file: <strong>{{ licencefile.filename }}</strong>
</div>
<div *ngIf="licenceFileError">
<strong>{{ licenceFileError }}</strong>
</div>
</ng-container>
</div>
</clr-tab-content>
</clr-tab>
<clr-tab>
<button clrTabLink>Paste licence</button>
<clr-tab-content>
<form class="clr-form license-key-form">
<p>Licence key:</p>
<div class="clr-control-container">
<textarea
[(ngModel)]="licenceKeyValue"
(mouseleave)="trimKeys()"
name="license-key-area"
placeholder="Paste licence key here"
class="clr-textarea"
></textarea>
</div> </div>
</clr-tab-content> </form>
</clr-tab>
<clr-tab> <form class="clr-form activation-key-form">
<button clrTabLink>Paste licence</button> <p>Activation key:</p>
<clr-tab-content> <div class="clr-control-container">
<form class="clr-form license-key-form"> <textarea
<p>Licence key:</p> [(ngModel)]="activationKeyValue"
<div class="clr-control-container"> (mouseleave)="trimKeys()"
<textarea name="activation-key-area"
[(ngModel)]="licenceKeyValue" placeholder="Paste activation key here"
(mouseleave)="trimKeys()" class="clr-textarea"
name="license-key-area" ></textarea>
placeholder="Paste licence key here" </div>
class="clr-textarea" </form>
></textarea> </clr-tab-content>
</div> </clr-tab>
</form> </clr-tabs>
<form class="clr-form activation-key-form"> <button
<p>Activation key:</p> (click)="applyKeys()"
<div class="clr-control-container"> class="btn btn-primary apply-keys"
<textarea [clrLoading]="applyingKeys"
[(ngModel)]="activationKeyValue" [disabled]="disableApplyButton"
(mouseleave)="trimKeys()" >
name="activation-key-area" Apply licence keys
placeholder="Paste activation key here" </button>
class="clr-textarea"
></textarea>
</div>
</form>
</clr-tab-content>
</clr-tab>
</clr-tabs>
</div>
<div class="card-footer d-flex clr-align-items-center"> <button
<button *ngIf="isAppFreeTier.value"
(click)="applyKeys()" routerLink="/"
class="btn btn-primary apply-keys" class="btn btn-sm btn-link"
[clrLoading]="applyingKeys" >
[disabled]="disableApplyButton" Continue with free tier
> </button>
Apply licence keys
</button>
<button
*ngIf="isAppFreeTier.value"
routerLink="/"
class="btn btn-sm btn-link"
>
Continue with free tier
</button>
</div>
</div> </div>
</div> </div>

View File

@ -0,0 +1,52 @@
:host {
height: calc(100% - 96px);
padding: 20px 20px;
}
.card {
margin-top: 0;
}
.key-error {
font-size: 16px;
}
.misskey {
color: #E74C3C;
}
.license-key-form, .activation-key-form {
padding: 0;
.clr-control-container {
width: 100%;
textarea {
width: 100%;
height: 170px;
max-height: 170px;
min-height: 170px;
resize: none;
}
}
}
.apply-keys {
height: 40px;
width: 200px;
}
.drop-area {
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
border: 2px dashed #b2b2b2;
border-radius: 4px;
cursor: pointer;
margin: 10px 0;
}
clr-tabs button {
box-shadow: none !important
}

View File

@ -1,8 +1,7 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router' import { ActivatedRoute, Router } from '@angular/router'
import { AppService, LicenceService, SasService } from '../services' import { AppService, LicenceService, SasService } from '../services'
import { LicenseKeyData } from '../models/LicenseKeyData' import { LicenseKeyData } from '../models/LicenseKeyData'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'
enum LicenseActions { enum LicenseActions {
key = 'key', key = 'key',
@ -14,8 +13,7 @@ enum LicenseActions {
@Component({ @Component({
selector: 'app-licensing', selector: 'app-licensing',
templateUrl: './licensing.component.html', templateUrl: './licensing.component.html',
styleUrls: ['./licensing.component.scss'], styleUrls: ['./licensing.component.scss']
encapsulation: ViewEncapsulation.None
}) })
export class LicensingComponent implements OnInit { export class LicensingComponent implements OnInit {
public action: LicenseActions | null = null public action: LicenseActions | null = null
@ -118,12 +116,8 @@ export class LicensingComponent implements OnInit {
this.sasService this.sasService
.request('admin/registerkey', table) .request('admin/registerkey', table)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
if ( if (res.return && res.return[0] && res.return[0].MSG === 'SUCCESS') {
res.adapterResponse.return &&
res.adapterResponse.return[0] &&
res.adapterResponse.return[0].MSG === 'SUCCESS'
) {
location.replace(location.href.split('#')[0]) location.replace(location.href.split('#')[0])
} }
}) })

View File

@ -3,7 +3,6 @@
<clr-tree-node *ngIf="libraryList" class="search-node"> <clr-tree-node *ngIf="libraryList" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchLibTreeInput #searchLibTreeInput
placeholder="Libraries" placeholder="Libraries"
@ -43,7 +42,6 @@
<clr-tree-node *ngIf="library['tables']" class="search-node"> <clr-tree-node *ngIf="library['tables']" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchTreeInput #searchTreeInput
placeholder="Tables" placeholder="Tables"
@ -87,7 +85,6 @@
<clr-tree-node *ngIf="libTable['columns']" class="search-node"> <clr-tree-node *ngIf="libTable['columns']" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchTreeInput #searchTreeInput
placeholder="Columns" placeholder="Columns"
@ -141,9 +138,7 @@
size="60" size="60"
class="is-info icon-dc-fill" class="is-info icon-dc-fill"
></clr-icon> ></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section"> <h3 class="text-center color-gray">Please select a column or table</h3>
Please select a column or table
</p>
</div> </div>
<ng-container *ngIf="column || table"> <ng-container *ngIf="column || table">
@ -185,13 +180,13 @@
<button <button
(click)="limitDotDepth = true" (click)="limitDotDepth = true"
type="button" type="button"
class="btn btn-outline mr-5" class="btn btn-outline"
> >
Limit depth Limit depth
</button> </button>
<!-- <button class="btn btn-outline" (click)='showSvg()'> Open in New Tab </button> --> <!-- <button class="btn btn-outline" (click)='showSvg()'> Open in New Tab </button> -->
<div class="btn-group direction d-block"> <div class="btn-group d-block">
<div <div
class="radio btn" class="radio btn"
(click)=" (click)="

View File

@ -0,0 +1,79 @@
.toggle-switch input[type=checkbox]:checked+label:before {
border-color: #314351;
background-color: #314351!important;
transition: .15s ease-in;
transition-property: border-color,background-color;
}
#graph{
height: calc(100vh - 195px);
overflow: hidden;
text-align: center;
display: block;
width: 100%;
border: 1px solid #e4e4e4;
margin-top: 10px;
}
.selection-wrapper {
width: 100%;
max-width: 670px;
}
.column-active {
background: #d8e3e9;
color: black;
}
.content-area {
padding: 0.5rem !important;
.card {
min-height: calc(100vh - 120px);
.card-block {
padding: 0.5rem 0.35rem !important;
}
}
}
clr-tree-node button {
white-space: nowrap;
}
.graph-render-spinner {
position: absolute;
top: 0;
width: 100%;
display: flex;
justify-content: center;
margin-top: 10px;
}
.biglineage-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-footer {
p {
margin: 0;
}
}
.lineage-title-wrapper {
left: 12px;
}
.max-depth-input {
width: 100%;
}
@media (max-width: 768px) {
.toggle-switch-container {
margin-bottom: 20px;
}
}

View File

@ -1,4 +1,4 @@
import { Component, ViewEncapsulation } from '@angular/core' import { Component } from '@angular/core'
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { globals } from '../_globals' import { globals } from '../_globals'
import * as d3Viz from 'd3-graphviz' import * as d3Viz from 'd3-graphviz'
@ -9,7 +9,6 @@ import { SasService } from '../services/sas.service'
import * as saveSvg from 'save-svg-as-png' import * as saveSvg from 'save-svg-as-png'
import { LoggerService } from '../services/logger.service' import { LoggerService } from '../services/logger.service'
import { LicenceService } from '../services/licence.service' import { LicenceService } from '../services/licence.service'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'
const moment = require('moment') const moment = require('moment')
@Component({ @Component({
@ -18,8 +17,7 @@ const moment = require('moment')
templateUrl: './lineage.component.html', templateUrl: './lineage.component.html',
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class LineageComponent { export class LineageComponent {
public switchFlag: boolean = false public switchFlag: boolean = false
@ -117,8 +115,8 @@ export class LineageComponent {
await this.sasService await this.sasService
.request('lineage/getmetacols', libTable) .request('lineage/getmetacols', libTable)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.columnsList = res.adapterResponse.metacols this.columnsList = res.metacols
if (this.columnsList && this.columnsList.length > 0) { if (this.columnsList && this.columnsList.length > 0) {
// this.column = this.columnsList[0]['COLURI'] // this.column = this.columnsList[0]['COLURI']
@ -176,8 +174,8 @@ export class LineageComponent {
let libTable = { SASControlTable: [{ liburi: $event }] } let libTable = { SASControlTable: [{ liburi: $event }] }
await this.sasService await this.sasService
.request('lineage/getmetatables', libTable) .request('lineage/getmetatables', libTable)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.tablesList = res.adapterResponse.metatables this.tablesList = res.metatables
if (this.tablesList && this.tablesList.length > 0) { if (this.tablesList && this.tablesList.length > 0) {
library['tables'] = this.tablesList library['tables'] = this.tablesList
@ -297,8 +295,8 @@ export class LineageComponent {
} else { } else {
await this.sasService await this.sasService
.request('public/viewlibs', null) .request('public/viewlibs', null)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.libraryList = res.adapterResponse.saslibs this.libraryList = res.saslibs
this.helperService.displayLibraries(this.libraryList) this.helperService.displayLibraries(this.libraryList)
if (this.libraryList) { if (this.libraryList) {
@ -404,8 +402,8 @@ export class LineageComponent {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
this.sasService this.sasService
.request('lineage/fetchtablelineage', libTable) .request('lineage/fetchtablelineage', libTable)
.then(async (res: RequestWrapperResponse) => { .then(async (res: any) => {
if (res.adapterResponse.flatdata.length > 0) { if (res.flatdata.length > 0) {
if (this.licenceService.checkLineageLimit()) { if (this.licenceService.checkLineageLimit()) {
this.eventService.showInfoModal( this.eventService.showInfoModal(
'Notice', 'Notice',
@ -423,22 +421,20 @@ export class LineageComponent {
} }
this.lineageTableName = this.lineageTableName =
res.adapterResponse.info[0].LIBREF + res.info[0].LIBREF + '.' + res.info[0].TABLENAME
'.' +
res.adapterResponse.info[0].TABLENAME
let dotArray = res.adapterResponse.finalfinal let dotArray = res.finalfinal
let vizTmp: string = '' let vizTmp: string = ''
for (let i = 0; i < dotArray.length; i++) { for (let i = 0; i < dotArray.length; i++) {
vizTmp += unescape(dotArray[i].LINE) + '\n' vizTmp += unescape(dotArray[i].LINE) + '\n'
} }
this.flatdata = res.adapterResponse.flatdata this.flatdata = res.flatdata
if (this.libraryList) { if (this.libraryList) {
let libraryToSelect = this.libraryList.find((library: any) => let libraryToSelect = this.libraryList.find((library: any) =>
res.adapterResponse.info[0].LIBURI.toUpperCase().includes( res.info[0].LIBURI.toUpperCase().includes(
library.LIBRARYID.toUpperCase() library.LIBRARYID.toUpperCase()
) )
) )
@ -454,7 +450,7 @@ export class LineageComponent {
if (libraryToSelect['tables']) { if (libraryToSelect['tables']) {
tableToSelect = libraryToSelect['tables'].find((table: any) => tableToSelect = libraryToSelect['tables'].find((table: any) =>
table.TABLEURI.toUpperCase().includes( table.TABLEURI.toUpperCase().includes(
res.adapterResponse.info[0].TABLEID.toUpperCase() res.info[0].TABLEID.toUpperCase()
) )
) )
@ -499,10 +495,10 @@ export class LineageComponent {
.replace(/\sds:/g, '\nds:') .replace(/\sds:/g, '\nds:')
.replace(/\s\n/g, '\n') .replace(/\s\n/g, '\n')
this.idlookup = res.adapterResponse.idlookup this.idlookup = res.idlookup
if (res.adapterResponse.finalfinal.length > this.largeDotFileLimit) { if (res.finalfinal.length > this.largeDotFileLimit) {
this.largeDotFileLines = res.adapterResponse.finalfinal.length this.largeDotFileLines = res.finalfinal.length
} else { } else {
this.buildGraph() this.buildGraph()
} }
@ -623,8 +619,8 @@ export class LineageComponent {
return new Promise<void>((resolve, reject) => { return new Promise<void>((resolve, reject) => {
this.sasService this.sasService
.request('lineage/fetchcollineage', libTable) .request('lineage/fetchcollineage', libTable)
.then(async (res: RequestWrapperResponse) => { .then(async (res: any) => {
if (res.adapterResponse.flatdata.length > 0) { if (res.flatdata.length > 0) {
if (this.licenceService.checkLineageLimit()) { if (this.licenceService.checkLineageLimit()) {
this.eventService.showInfoModal( this.eventService.showInfoModal(
'Notice', 'Notice',
@ -635,21 +631,18 @@ export class LineageComponent {
} }
} }
if (typeof res.adapterResponse === 'string') { if (typeof res === 'string') {
this.vizInput = 'digraph G {SAS Error}' this.vizInput = 'digraph G {SAS Error}'
this.buildGraph() this.buildGraph()
return return
} }
this.lineageTableName = this.lineageTableName = res.info[0].LIBREF + '.' + res.info[0].TABNAME
res.adapterResponse.info[0].LIBREF + this.lineageColumnName = res.info[0].COLNAME
'.' +
res.adapterResponse.info[0].TABNAME
this.lineageColumnName = res.adapterResponse.info[0].COLNAME
this.idlookup = res.adapterResponse.idlookup this.idlookup = res.idlookup
let dotArray = res.adapterResponse.fromsas let dotArray = res.fromsas
let vizTmp: string = '' let vizTmp: string = ''
for (let i = 0; i < dotArray.length; i++) { for (let i = 0; i < dotArray.length; i++) {
vizTmp += unescape(dotArray[i].STRING) + '\n' vizTmp += unescape(dotArray[i].STRING) + '\n'
@ -660,13 +653,14 @@ export class LineageComponent {
.replace(/\sds:/g, '\nds:') .replace(/\sds:/g, '\nds:')
.replace(/\s\n/g, '\n') .replace(/\s\n/g, '\n')
this.flatdata = res.adapterResponse.flatdata this.flatdata = res.flatdata
if (this.libraryList) { if (this.libraryList) {
let libraryToSelect = this.libraryList.find((library: any) => let libraryToSelect = this.libraryList.find(
res.adapterResponse.info[0]?.LIBURI?.toUpperCase()?.includes( (library: any) =>
library?.LIBRARYID?.toUpperCase() res.info[0]?.LIBURI?.toUpperCase()?.includes(
) library?.LIBRARYID?.toUpperCase()
)
) )
let tableToSelect: any let tableToSelect: any
@ -679,8 +673,7 @@ export class LineageComponent {
if (libraryToSelect['tables']) { if (libraryToSelect['tables']) {
tableToSelect = libraryToSelect['tables'].find( tableToSelect = libraryToSelect['tables'].find(
(table: any) => (table: any) => table.TABLEURI === res.info[0].TABURI
table.TABLEURI === res.adapterResponse.info[0].TABURI
) )
if (tableToSelect) { if (tableToSelect) {
@ -722,8 +715,8 @@ export class LineageComponent {
} }
} }
if (res.adapterResponse.fromsas.length > this.largeDotFileLimit) { if (res.fromsas.length > this.largeDotFileLimit) {
this.largeDotFileLines = res.adapterResponse.fromsas.length this.largeDotFileLines = res.fromsas.length
} else { } else {
this.buildGraph() this.buildGraph()
} }

View File

@ -22,7 +22,6 @@
<clr-tree-node *ngIf="metaDataList" class="search-node"> <clr-tree-node *ngIf="metaDataList" class="search-node">
<div class="tree-search-wrapper"> <div class="tree-search-wrapper">
<input <input
appStealFocus
clrInput clrInput
#searchLibTreeInput #searchLibTreeInput
placeholder="search SAS Types" placeholder="search SAS Types"
@ -73,9 +72,7 @@
size="60" size="60"
class="is-info icon-dc-fill" class="is-info icon-dc-fill"
></clr-icon> ></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section"> <h3 class="text-center color-gray">Please select a type</h3>
Please select a type
</p>
</div> </div>
<div class="loadingSpinner" *ngIf="loading"> <div class="loadingSpinner" *ngIf="loading">
@ -126,18 +123,12 @@
[class.object-header]="!entry.count" [class.object-header]="!entry.count"
class="full-width" class="full-width"
> >
<div> <clr-icon
<clr-icon *ngIf="!entry.count"
*ngIf="!entry.count" shape="rack-server"
shape="rack-server" ></clr-icon>
></clr-icon> <clr-icon *ngIf="entry.count" shape="block"></clr-icon>
<clr-icon {{ entry.display }}
*ngIf="entry.count"
shape="block"
></clr-icon>
{{ entry.display }}
</div>
<p class="float-right object-uri" *ngIf="!entry.count"> <p class="float-right object-uri" *ngIf="!entry.count">
{{ entry.URI }} {{ entry.URI }}
</p> </p>
@ -172,15 +163,9 @@
[clrExpandable]="true" [clrExpandable]="true"
> >
<div [class.object-header]="!entry.count" class="full-width"> <div [class.object-header]="!entry.count" class="full-width">
<div> <clr-icon *ngIf="!entry.count" shape="rack-server"></clr-icon>
<clr-icon <clr-icon *ngIf="entry.count" shape="block"></clr-icon>
*ngIf="!entry.count" {{ entry.display }}
shape="rack-server"
></clr-icon>
<clr-icon *ngIf="entry.count" shape="block"></clr-icon>
{{ entry.display }}
</div>
<p class="float-right object-uri" *ngIf="!entry.count"> <p class="float-right object-uri" *ngIf="!entry.count">
{{ entry.URI }} {{ entry.URI }}
</p> </p>

View File

@ -0,0 +1,67 @@
.objects-col{
height: 75vh;
overflow: scroll;
border: 1px solid #cccccc;
background: white;
border-radius: 4px;
}
.cols-head {
background: #fafafa;
border: 1px solid #cccccc;
padding: 10px;
display: flex;
}
.object-text {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-left: 10px;
flex: 1;
}
.repo-dropdown{
margin-right: 15px;
margin-left: 15px;
margin-bottom: 10px;
}
.clr-accordion-title{
width: 100%;
}
.float-right{
margin: 0px;
float: right;
}
.full-width{
width: 100%;
}
.object-uri{
margin: 0px;
margin-top: 5px;
}
.object-header{
padding-left: 3px;
padding-right: 3px;
}
.object-header:hover{
background-color: #d8e3e9;
border-radius: 3px;
}
.datagrid-host{
display: unset !important;
}
.card {
margin-top: 0;
flex: 1;
display: flex;
flex-direction: column;
}
.content-area {
padding: 0.5rem !important;
display: flex;
flex-direction: column;
}

View File

@ -1,5 +1,5 @@
import { Location } from '@angular/common' import { Location } from '@angular/common'
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router' import { ActivatedRoute, Router } from '@angular/router'
import { ClrDatagridStringFilterInterface } from '@clr/angular' import { ClrDatagridStringFilterInterface } from '@clr/angular'
import { Observable, of } from 'rxjs' import { Observable, of } from 'rxjs'
@ -9,7 +9,6 @@ import { SasService } from '../services/sas.service'
import { globals } from '../_globals' import { globals } from '../_globals'
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { RequestWrapperResponse } from '../models/request-wrapper/RequestWrapperResponse'
interface MetaData { interface MetaData {
NAME: any NAME: any
@ -50,8 +49,7 @@ class ValueFilter implements ClrDatagridStringFilterInterface<MetaData> {
styleUrls: ['./metadata.component.scss'], styleUrls: ['./metadata.component.scss'],
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class MetadataComponent implements OnInit { export class MetadataComponent implements OnInit {
metaDataList: Array<any> | undefined metaDataList: Array<any> | undefined
@ -111,52 +109,44 @@ export class MetadataComponent implements OnInit {
this.metatypesLoading = false this.metatypesLoading = false
this.metaDataSearch = globals.metadata.metaDataSearch this.metaDataSearch = globals.metadata.metaDataSearch
} else { } else {
this.sasService this.sasService.request('metanav/metatypes', null).then((res: any) => {
.request('metanav/metatypes', null) this.metaDataList = res.types
.then((res: RequestWrapperResponse) => { globals.metadata.metaDataList = this.metaDataList
this.metaDataList = res.adapterResponse.types this.loading = false
globals.metadata.metaDataList = this.metaDataList this.metatypesLoading = false
this.loading = false })
this.metatypesLoading = false
})
this.sasService this.sasService.request('metanav/metarepos', null).then((res: any) => {
.request('metanav/metarepos', null) let foundation = false
.then((res: RequestWrapperResponse) => { this.repositories = []
let foundation = false for (let index = 0; index < res.outrepos.length; index++) {
this.repositories = [] this.repositories.push(res.outrepos[index].NAME)
for ( if (res.outrepos[index].NAME === 'Foundation') {
let index = 0; foundation = true
index < res.adapterResponse.outrepos.length;
index++
) {
this.repositories.push(res.adapterResponse.outrepos[index].NAME)
if (res.adapterResponse.outrepos[index].NAME === 'Foundation') {
foundation = true
}
} }
if (foundation) { }
this.repository = 'Foundation' if (foundation) {
} else { this.repository = 'Foundation'
this.repository = res.adapterResponse.outrepos[0].NAME } else {
} this.repository = res.outrepos[0].NAME
globals.metadata.metaRepositories = this.repositories }
globals.metadata.selectedRepository = this.repository globals.metadata.metaRepositories = this.repositories
if (this.objectRoute) { globals.metadata.selectedRepository = this.repository
this.eventService.closeSidebar() if (this.objectRoute) {
this.showData = true this.eventService.closeSidebar()
let name = '' this.showData = true
let id = this.route.snapshot.params['objectID'] let name = ''
// let temp = this.router.url.split("%20").join(" ").split("/").reverse(); let id = this.route.snapshot.params['objectID']
this.metaObjectList = [] // let temp = this.router.url.split("%20").join(" ").split("/").reverse();
this.metaObjectList.push({ ID: id, NAME: name }) this.metaObjectList = []
this.metaObjectShowList = this.metaObjectList this.metaObjectList.push({ ID: id, NAME: name })
this.metaObjectOnClick( this.metaObjectShowList = this.metaObjectList
this.metaObjectShowList[0].ID, this.metaObjectOnClick(
this.metaObjectShowList[0] this.metaObjectShowList[0].ID,
) this.metaObjectShowList[0]
} )
}) }
})
} }
} }
@ -193,64 +183,56 @@ export class MetadataComponent implements OnInit {
const data: any = { const data: any = {
SASControlTable: [{ metatype: $event, repo: this.repository }] SASControlTable: [{ metatype: $event, repo: this.repository }]
} }
this.sasService this.sasService.request('metanav/metaobjects', data).then((res: any) => {
.request('metanav/metaobjects', data) this.metaObjectList = res.objects
.then((res: RequestWrapperResponse) => { this.getMetaObjectAttributes(this.metaObjectSize)
this.metaObjectList = res.adapterResponse.objects this.loading = false
this.getMetaObjectAttributes(this.metaObjectSize) this.assoTypeSelected = $event
this.loading = false this.eventService.closeSidebar()
this.assoTypeSelected = $event this.showData = true
this.eventService.closeSidebar() })
this.showData = true
})
} }
public async selectmetaObject($event: any, metaData?: any) { public async selectmetaObject($event: any, metaData?: any) {
let data: any = { let data: any = {
SASControlTable: [{ objecturi: $event }] SASControlTable: [{ objecturi: $event }]
} }
this.sasService this.sasService.request('metanav/metadetails', data).then((res: any) => {
.request('metanav/metadetails', data) this.metaObjectAssociations = res.associations
.then((res: RequestWrapperResponse) => { this.root$ = of(this.getAssosiationsCount(res.associations))
this.metaObjectAssociations = res.adapterResponse.associations this.showAcc = true
this.root$ = of( this.showTable = true
this.getAssosiationsCount(res.adapterResponse.associations) let metaObjectName = res.attributes.find(
(x: any) => x.NAME === 'Name'
).VALUE
this.assoObjectSelected = metaObjectName
metaData.NAME = metaObjectName
let url = this.router.url
if (this.objectRoute) {
// this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
this.location.replaceState(
url.slice(0, url.lastIndexOf('object')) +
'object/' +
$event.slice(1 + $event.indexOf('\\'))
) )
this.showAcc = true } else {
this.showTable = true // this.location.replaceState(url + "/object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
let metaObjectName = res.adapterResponse.attributes.find( this.location.replaceState(
(x: any) => x.NAME === 'Name' url + '/object/' + $event.slice(1 + $event.indexOf('\\'))
).VALUE )
this.assoObjectSelected = metaObjectName }
metaData.NAME = metaObjectName this.metaObjectAttributes = res.attributes
let url = this.router.url })
if (this.objectRoute) {
// this.location.replaceState(url.slice(0, url.lastIndexOf("object")) + "object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
this.location.replaceState(
url.slice(0, url.lastIndexOf('object')) +
'object/' +
$event.slice(1 + $event.indexOf('\\'))
)
} else {
// this.location.replaceState(url + "/object/" + $event.slice(1 + $event.indexOf("\\")) + "/" + escape(metaData.NAME));
this.location.replaceState(
url + '/object/' + $event.slice(1 + $event.indexOf('\\'))
)
}
this.metaObjectAttributes = res.adapterResponse.attributes
})
} }
public async selectAssosiationsDetails($event: any, metaData?: any) { public async selectAssosiationsDetails($event: any, metaData?: any) {
let data: any = { let data: any = {
SASControlTable: [{ objecturi: $event }] SASControlTable: [{ objecturi: $event }]
} }
this.sasService this.sasService.request('metanav/metadetails', data).then((res: any) => {
.request('metanav/metadetails', data) this.metaObjectAttributes = res.attributes
.then((res: RequestWrapperResponse) => { this.showTable = true
this.metaObjectAttributes = res.adapterResponse.attributes })
this.showTable = true
})
} }
public getAssosiationsCount(assosiationList: Array<any>) { public getAssosiationsCount(assosiationList: Array<any>) {
@ -262,7 +244,7 @@ export class MetadataComponent implements OnInit {
details: [] details: []
}) })
} }
let assocObj: any = assosiationsHash.get(assosiation.ASSOC) let assocObj = assosiationsHash.get(assosiation.ASSOC)
assocObj.count++ assocObj.count++
assocObj.details.push({ assocObj.details.push({
ASSOCURI: assosiation.ASSOCURI, ASSOCURI: assosiation.ASSOCURI,
@ -272,7 +254,7 @@ export class MetadataComponent implements OnInit {
}) })
} }
let assocGrouped: Array<any> = [] let assocGrouped: Array<any> = []
assosiationsHash.forEach(function (val: any, key) { assosiationsHash.forEach(function (val, key) {
assocGrouped.push({ assocGrouped.push({
ASSOC: key, ASSOC: key,
count: val.count, count: val.count,
@ -312,9 +294,9 @@ export class MetadataComponent implements OnInit {
} }
return this.sasService return this.sasService
.request('metanav/metadetails', data) .request('metanav/metadetails', data)
.then((res: RequestWrapperResponse) => { .then((res: any) => {
this.showTable = true this.showTable = true
this.metaObjectAttributes = res.adapterResponse.attributes this.metaObjectAttributes = res.attributes
this.assoObjectSelected = asso.NAME this.assoObjectSelected = asso.NAME
let url = this.router.url let url = this.router.url
if (this.objectRoute) { if (this.objectRoute) {
@ -332,7 +314,7 @@ export class MetadataComponent implements OnInit {
asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\')) asso.ASSOCURI.slice(1 + asso.ASSOCURI.indexOf('\\'))
) )
} }
return this.getAssosiationsCount(res.adapterResponse.associations) return this.getAssosiationsCount(res.associations)
}) })
} }

View File

@ -1,9 +0,0 @@
export interface AppSettings {
persistSelectedTheme: boolean
selectedTheme: AppThemes
}
export enum AppThemes {
light = 'light',
dark = 'dark'
}

View File

@ -1 +0,0 @@
export type FileUploadEncoding = 'UTF-8' | 'WLATIN1'

View File

@ -6,7 +6,6 @@ export interface FilterClause {
operators: string[] operators: string[]
type: string type: string
value: any value: any
valueVariable: boolean
values: { formatted: string; unformatted: any }[] values: { formatted: string; unformatted: any }[]
variable: string variable: string
} }

View File

@ -1,29 +0,0 @@
import { DcValidator } from '../shared/dc-validator/dc-validator'
import { FileUploadEncoding } from './FileUploadEncoding'
import { FileUploader } from './FileUploader.class'
import { ExcelRule } from './TableData'
import XLSX from 'xlsx'
export interface ParseParams {
file: File
password?: string
dcValidator: DcValidator
/**
* If workbook is provided, parse function will not run a XLSX.read()
* it will use this property instead. So the client must do a file read beforehand
*/
workbook?: XLSX.WorkBook
/**
* Parse function will manipulate and return the uploader array which can be provided with files already in the queue
* Otherwise new empty instance will be created.
*/
uploader?: FileUploader
headerPks: string[]
headerArray: string[]
headerShow: string[]
timeHeaders: string[]
dateHeaders: string[]
dateTimeHeaders: string[]
xlRules: ExcelRule[]
encoding?: FileUploadEncoding
}

View File

@ -1,15 +0,0 @@
import { FileUploader } from './FileUploader.class'
import FoundRangeInfo from './RangeInfo'
export interface ParseResult {
/**
* In case of CSV file, won't be returned
*/
data?: any[]
/**
* In case of CSV file, won't be returned
*/
headerShow?: string[]
rangeSheetRes?: FoundRangeInfo
uploader: FileUploader
}

View File

@ -1,13 +0,0 @@
export default interface FoundRangeInfo {
found: boolean
sheetName: string
rangeStartAddress: string
rangeEndAddress: string
rangeAddress: string
missingHeaders: MissingHeaders[]
}
export interface MissingHeaders {
sheetName: string
missingHeaders: string[]
}

View File

@ -1,13 +0,0 @@
import { MissingHeaders } from './RangeInfo'
export interface SearchDataExcelResult {
missing?: MissingHeaders[]
found?: {
data: any
arrayData: any[]
sheetName: string
headers: string[]
startAddress?: string
endAddress?: string
}
}

View File

@ -7,5 +7,4 @@ export default interface SheetInfo {
missingHeaders: string[] missingHeaders: string[]
rangeStartRow: number rangeStartRow: number
rangeStartCol: number rangeStartCol: number
rangeAddress?: string
} }

View File

@ -1,4 +0,0 @@
export interface UploadFileResponse {
adapterResponse: any
log?: string
}

View File

@ -1,4 +0,0 @@
export interface RequestWrapperResponse<responseType = any> {
adapterResponse: responseType
log?: string
}

View File

@ -4,12 +4,12 @@ import { DQData, SASParam } from '../TableData'
import { BaseSASResponse } from './common/BaseSASResponse' import { BaseSASResponse } from './common/BaseSASResponse'
import { DataFormat } from './common/DateFormat' import { DataFormat } from './common/DateFormat'
export interface EditorsGetDataServiceResponse { export interface EditorsGetdataServiceResponse {
data: EditorsGetDataSASResponse data: EditorsGetdataSASResponse
libds: string libds: string
} }
export interface EditorsGetDataSASResponse extends BaseSASResponse { export interface EditorsGetdataSASResponse extends BaseSASResponse {
$sasdata: $DataFormats $sasdata: $DataFormats
sasdata: Sasdata[] sasdata: Sasdata[]
sasparams: SASParam[] sasparams: SASParam[]
@ -17,7 +17,6 @@ export interface EditorsGetDataSASResponse extends BaseSASResponse {
dqrules: DQRule[] dqrules: DQRule[]
dsmeta: DSMeta[] dsmeta: DSMeta[]
dqdata: DQData[] dqdata: DQData[]
versions: Version[]
cols: Col[] cols: Col[]
maxvarlengths: Maxvarlength[] maxvarlengths: Maxvarlength[]
xl_rules: any[] xl_rules: any[]
@ -28,18 +27,6 @@ export interface DSMeta {
ODS_TABLE: string ODS_TABLE: string
NAME: string NAME: string
VALUE: string VALUE: string
[key: string]: string
}
export interface Version {
LOAD_REF: string
USER_NM: string
VERSION_DTTM: string
VERSION_DESC: string
CHANGED_RECORDS: number
NEW_RECORDS: number
DELETED_RECORDS: number
[key: string]: string | number
} }
export interface Sasdata { export interface Sasdata {

View File

@ -1,9 +0,0 @@
import { BaseSASResponse } from './common/BaseSASResponse'
export interface EditorsRestoreServiceResponse extends BaseSASResponse {
restore_out: RestoreOut[]
}
export interface RestoreOut {
LOADREF: string
}

View File

@ -1,34 +0,0 @@
import { BaseSASResponse } from './common/BaseSASResponse'
export interface EditorsStageDataSASResponse extends BaseSASResponse {
SYSDATE: string
SYSTIME: string
sasparams: Sasparam[]
_DEBUG: string
_PROGRAM: string
AUTOEXEC: string
MF_GETUSER: string
SYSCC: string
SYSENCODING: string
SYSERRORTEXT: string
SYSHOSTINFOLONG: string
SYSHOSTNAME: string
SYSPROCESSID: string
SYSPROCESSMODE: string
SYSPROCESSNAME: string
SYSJOBID: string
SYSSCPL: string
SYSSITE: string
SYSTCPIPHOSTNAME: string
SYSUSERID: string
SYSVLONG: string
SYSWARNINGTEXT: string
END_DTTM: string
MEMSIZE: string
}
export interface Sasparam {
STATUS: string | 'SUCCESS'
DSID: string
URL: string
}

View File

@ -1,19 +0,0 @@
import { NgModule } from '@angular/core'
import { RouterModule, Routes } from '@angular/router'
import { MultiDatasetRouteComponent } from '../routes/multi-dataset-route/multi-dataset-route.component'
import { MultiDatasetComponent } from './multi-dataset.component'
const routes: Routes = [
{
path: '',
component: MultiDatasetRouteComponent,
children: [{ path: '', component: MultiDatasetComponent }]
}
]
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class MultiDatasetRoutingModule {}

View File

@ -1,543 +0,0 @@
<app-sidebar>
<div *ngIf="datasetsLoading" class="my-10-mx-auto text-center">
<clr-spinner clrMedium></clr-spinner>
</div>
<div *ngIf="!parsedDatasets.length" class="text-center mb-10">
<button
(click)="fileUploadInput.click()"
id="browse-file"
class="btn btn-primary btn-sm"
[disabled]="selectedFile !== null || submittingCsv"
>
Browse file
</button>
<input
hidden
#fileUploadInput
id="file-upload"
type="file"
(change)="onFileChange($event)"
multiple
/>
</div>
<ng-container *ngIf="parsedDatasets.length && !submittedCsvDatasets.length">
<div *ngIf="!excelsSubmitted" class="text-center mb-10">
<button (click)="onDiscard()" class="btn btn-danger btn-sm mr-10">
Discard
</button>
<button
(click)="onSubmitAll()"
id="submit-all"
class="btn btn-primary btn-sm"
>
Submit All
</button>
</div>
<p cds-text="caption" class="ml-10 mb-10">Found tables:</p>
<clr-tree>
<clr-tree-node *ngFor="let dataset of parsedDatasets">
<button
(click)="onParsedDatasetClick(dataset)"
class="clr-treenode-link whitespace-nowrap d-flex clr-align-items-center"
[class.active]="dataset.active"
>
<ng-container *ngIf="dataset.submitResult">
<cds-icon
*ngIf="dataset.submitResult.error"
status="danger"
shape="exclamation-circle"
></cds-icon>
<cds-icon
*ngIf="dataset.submitResult.success"
status="success"
shape="check-circle"
></cds-icon>
</ng-container>
<ng-container *ngIf="!dataset.submitResult">
<ng-container *ngIf="dataset.datasource">
<cds-icon
*ngIf="!(dataset.datasource.length && dataset.parseResult)"
status="danger"
shape="exclamation-circle"
></cds-icon>
<cds-icon
*ngIf="dataset.datasource.length && dataset.parseResult"
shape="table"
></cds-icon>
</ng-container>
<ng-container *ngIf="!dataset.datasource">
<cds-icon *ngIf="!dataset.parsingTable" shape="table"></cds-icon>
<clr-spinner *ngIf="dataset.parsingTable" clrSmall></clr-spinner>
</ng-container>
</ng-container>
<span class="ml-5"> {{ dataset.libds }} </span>
</button>
</clr-tree-node>
</clr-tree>
</ng-container>
<ng-container *ngIf="submittedCsvDatasets.length">
<p cds-text="caption" class="ml-10 mb-10 mt-10">Submitted tables:</p>
<clr-tree>
<clr-tree-node *ngFor="let dataset of submittedCsvDatasets">
<button
(click)="onSubmittedCsvDatasetClick(dataset)"
class="clr-treenode-link whitespace-nowrap"
[class.active]="dataset.active"
>
<cds-icon
*ngIf="dataset.error"
status="danger"
shape="exclamation-circle"
></cds-icon>
<cds-icon
*ngIf="dataset.success"
status="success"
shape="check-circle"
></cds-icon>
<cds-icon shape="table"></cds-icon>
{{ dataset.libds }}
</button>
</clr-tree-node>
</clr-tree>
</ng-container>
<!-- <div *ngIf="librariesPaging" class="w-100 text-center">
<span class="spinner spinner-sm"> Loading... </span>
</div> -->
</app-sidebar>
<div #contentArea class="content-area">
<div class="card no-borders h-100 d-flex clr-flex-column">
<div
class="header-row clr-row justify-content-between clr-justify-content-center w-100 m-0"
>
<p cds-text="section">Multi Dataset Load</p>
</div>
<div
*ngIf="selectedFile === null && !submittingCsv"
class="no-table-selected pointer-events-none"
>
<clr-icon
shape="upload-cloud"
size="40"
class="is-info icon-dc-fill"
></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section">
Please upload a file
</p>
</div>
<ng-container *ngIf="selectedFile !== null || submittingCsv">
<ng-container *ngIf="!parsedDatasets.length && selectedFile !== null">
<div class="d-flex clr-justify-content-center mt-15">
<div class="dataset-input-wrapper">
<p cds-text="secondary regular" class="mb-5">
Selected file: <strong>{{ selectedFile.name }}</strong>
<clr-tooltip>
<cds-icon
clrTooltipTrigger
(click)="onDiscardFile()"
shape="trash"
status="danger"
class="ml-5 cursor-pointer"
></cds-icon>
<clr-tooltip-content> Discard the file </clr-tooltip-content>
</clr-tooltip>
</p>
<p cds-text="secondary regular" class="mb-20">
File size: <strong>{{ selectedFile.sizeMB }} MB</strong>
</p>
<p cds-text="secondary regular" class="mb-15">
Paste or type the list of datasets to upload:
</p>
<clr-control-helper class="mb-5"
>Each row is one dataset. We will automatically detect tables by
the sheetname and populate if any.</clr-control-helper
>
<hot-table
hotId="hotInstanceUserDataset"
id="hotTableUserDataset"
class="mt-15"
[afterGetColHeader]="afterGetColHeader"
[settings]="hotUserDatasets"
[licenseKey]="hotTableLicenseKey"
stretchH="all"
>
</hot-table>
<div class="dataset-selection-actions text-right mt-10">
<button
(click)="onStartParsingFile()"
id="continue-btn"
class="btn btn-primary btn-sm"
[disabled]="!matchedDatasets.length"
[clrLoading]="uploadLoading"
>
Continue
</button>
</div>
</div>
</div>
</ng-container>
<ng-container
*ngIf="parsedDatasets.length && !submittedCsvDatasets.length"
>
<div
*ngIf="!activeParsedDataset"
class="no-table-selected pointer-events-none"
>
<ng-container *ngIf="fileLoadingState !== FileLoadingState.parsed">
<clr-icon
shape="process-on-vm"
size="40"
class="is-info icon-dc-fill"
></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section">
{{ fileLoadingState }}...
</p>
</ng-container>
<ng-container *ngIf="fileLoadingState === FileLoadingState.parsed">
<clr-icon
shape="warning-standard"
size="40"
class="is-info icon-dc-fill"
></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section">
Please select a dataset on the left to review the data
</p>
</ng-container>
</div>
<ng-container *ngIf="activeParsedDataset">
<div
*ngIf="activeParsedDataset.submitResult"
class="d-flex clr-justify-content-between p-10 mt-15 submission-results"
>
<div>
<p cds-text="secondary regular" class="mb-10">
Submit Status:
<span
*ngIf="activeParsedDataset.submitResult?.success"
class="color-green"
><strong>SUCCESS</strong></span
>
<span
*ngIf="activeParsedDataset.submitResult?.error"
class="color-red"
><strong>ERROR</strong></span
>
</p>
<p
*ngIf="activeParsedDataset.submitResult?.error"
cds-text="secondary regular"
>
Error details:
</p>
</div>
<div>
<button
*ngIf="
!submittingCsv && activeParsedDataset.submitResult?.error
"
(click)="reSubmitTable(activeParsedDataset)"
class="btn btn-primary mt-10"
[clrLoading]="submitLoading"
>
Resubmit
</button>
<button
(click)="
downloadFile(
activeParsedDataset.submitResult.log ||
activeParsedDataset.submitResult.success ||
activeParsedDataset.submitResult.error
)
"
class="btn btn-primary-outline mt-10"
>
Download log
</button>
</div>
</div>
<div
*ngIf="activeParsedDataset.submitResult?.error"
class="error-field mt-15"
>
<div class="log-wrapper">
{{ activeParsedDataset.submitResult?.error | json }}
</div>
</div>
<div class="d-flex clr-justify-content-between p-10 mt-15">
<div>
<p cds-text="secondary regular" class="mb-10">
Found in range:
<ng-container *ngIf="activeParsedDataset.parseResult">
<strong
>"{{
activeParsedDataset.parseResult.rangeSheetRes?.sheetName
}}"!{{
activeParsedDataset.parseResult.rangeSheetRes
?.rangeAddress
}}</strong
>
</ng-container>
<ng-container *ngIf="!activeParsedDataset.parseResult">
<strong *ngIf="!activeParsedDataset.parsingTable"
>No data found</strong
>
<span
*ngIf="activeParsedDataset.parsingTable"
class="d-flex clr-align-items-center"
>
<strong>Searching for the data...</strong>
<clr-spinner class="ml-5" clrSmall></clr-spinner>
</span>
</ng-container>
</p>
<p cds-text="secondary regular">
Dataset:
<strong>
<clr-tooltip>
<a
clrTooltipTrigger
[routerLink]="'/editor/' + activeParsedDataset.libds"
>{{ activeParsedDataset.libds }}</a
>
<clr-tooltip-content
[clrPosition]="'top-right'"
[clrSize]="'sm'"
>
Click to edit the table
</clr-tooltip-content>
</clr-tooltip>
</strong>
</p>
</div>
<div>
<clr-toggle-wrapper>
<input
type="checkbox"
clrToggle
[(ngModel)]="activeParsedDataset.includeInSubmission"
name="options"
[disabled]="
!(
activeParsedDataset.datasource &&
activeParsedDataset.parseResult
)
"
required
value="option1"
/>
<label>Include in submission</label>
</clr-toggle-wrapper>
</div>
</div>
<div *ngIf="isHotHidden" class="text-center w-100">
<clr-spinner class="spinner-md"></clr-spinner>
</div>
<hot-table
hotId="hotInstance"
id="hotTable"
class="mt-15"
[afterGetColHeader]="afterGetColHeader"
[className]="['htDark', 'htCustomHidden']"
[licenseKey]="hotTableLicenseKey"
[multiColumnSorting]="true"
[viewportRowRenderingOffset]="50"
[manualColumnResize]="true"
[filters]="true"
stretchH="all"
>
</hot-table>
</ng-container>
</ng-container>
<ng-container *ngIf="submittedCsvDatasets.length">
<div
*ngIf="!activeSubmittedCsvDataset"
class="no-table-selected pointer-events-none"
>
<clr-icon
shape="warning-standard"
size="40"
class="is-info icon-dc-fill"
></clr-icon>
<p class="text-center color-gray mt-10" cds-text="section">
Please select a dataset on the left to review the submit results
</p>
</div>
</ng-container>
<ng-container *ngIf="activeSubmittedCsvDataset">
<div class="d-flex clr-justify-content-between p-10">
<div>
<p cds-text="secondary regular" class="mb-10">
Matched with dataset:
<strong>
<clr-tooltip>
<a
clrTooltipTrigger
[routerLink]="'/editor/' + activeSubmittedCsvDataset.libds"
>{{ activeSubmittedCsvDataset.libds }}</a
>
<clr-tooltip-content
[clrPosition]="'top-right'"
[clrSize]="'sm'"
>
Click to edit the table
</clr-tooltip-content>
</clr-tooltip>
</strong>
</p>
<p cds-text="secondary regular" class="mb-10">
Status:
<span
*ngIf="activeSubmittedCsvDataset.success"
class="color-green"
><strong>SUCCESS</strong></span
>
<span *ngIf="activeSubmittedCsvDataset.error" class="color-red"
><strong>ERROR</strong></span
>
</p>
<p
*ngIf="activeSubmittedCsvDataset.error"
cds-text="secondary regular"
>
Error details:
</p>
</div>
<div>
<button
(click)="
downloadFile(
activeSubmittedCsvDataset.success ||
activeSubmittedCsvDataset.error
)
"
class="btn btn-primary-outline mt-10"
>
Download log
</button>
</div>
</div>
<div *ngIf="activeSubmittedCsvDataset.error" class="error-field mt-15">
<div class="log-wrapper">
{{ activeSubmittedCsvDataset.error | json }}
</div>
</div>
</ng-container>
</ng-container>
<!-- <div>
<p
*ngIf="
licenceState.value.viewer_rows_allowed !== Infinity &&
hotTable.data &&
hotTable.data.length > licenceState.value.viewer_rows_allowed
"
class="mt-2-i w-100 text-center"
>
To display more than {{ licenceState.value.viewer_rows_allowed }} rows,
contact <contact-link />
</p>
</div> -->
</div>
</div>
<clr-modal [(clrModalOpen)]="showSubmitReasonModal" [clrModalClosable]="false">
<h3 class="modal-title">
Submit {{ tablesToSubmit.length }}
{{ tablesToSubmit.length === 1 ? 'table' : 'tables' }} for approval
</h3>
<div class="modal-body">
<p
*ngIf="licenceState.value.submit_rows_limit !== Infinity"
cds-text="body"
class="licence-limit-notice mt-0 mb-15"
>
Due to current licence, only
{{ licenceState.value.submit_rows_limit }} rows in each file will be
submitted. To remove the restriction, contact
support&#64;datacontroller.io.
</p>
<div class="text-area-full-width">
<label for="formFields_8" class="mb-5 d-block">Message</label>
<textarea
clrTextarea
[(ngModel)]="submitReasonMessage"
tabindex="0"
class="submit-reason"
type="text"
id="formFields_8"
></textarea>
</div>
<p cds-text="caption_clean" class="mt-10">
Tables will be sent sequentially, logs will be available after all tables
are submitted.
</p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-outline"
[disabled]="submitLoading"
(click)="showSubmitReasonModal = false"
>
Cancel
</button>
<button
type="button"
id="submit-tables"
class="btn btn-primary"
[clrLoading]="submitLoading"
(click)="submitTables()"
>
Submit
</button>
</div>
</clr-modal>
<clr-modal [(clrModalOpen)]="csvSubmitting" [clrModalClosable]="false">
<h3 class="modal-title">
Submitting {{ csvFiles.length }} CSV
{{ csvFiles.length === 1 ? 'file' : 'files' }}
</h3>
<div class="modal-body">
<div class="text-center">
<clr-spinner clrMedium></clr-spinner>
</div>
<p cds-text="caption_clean" class="mt-10 text-center">
This will take few moments
</p>
</div>
</clr-modal>

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { ClarityModule } from '@clr/angular'
import { HotTableModule } from '@handsontable/angular'
import { registerAllModules } from 'handsontable/registry'
import { AppSharedModule } from '../app-shared.module'
import { DirectivesModule } from '../directives/directives.module'
import { DcTreeModule } from '../shared/dc-tree/dc-tree.module'
import { MultiDatasetComponent } from './multi-dataset.component'
import { MultiDatasetRoutingModule } from './multi-dataset-routing.module'
import { MultiDatasetRouteComponent } from '../routes/multi-dataset-route/multi-dataset-route.component'
// register Handsontable's modules
registerAllModules()
@NgModule({
declarations: [MultiDatasetRouteComponent, MultiDatasetComponent],
imports: [
HotTableModule,
MultiDatasetRoutingModule,
FormsModule,
ClarityModule,
AppSharedModule,
CommonModule,
DcTreeModule,
DirectivesModule
],
exports: [MultiDatasetComponent]
})
export class MultiDatasetModule {}

View File

@ -1,4 +1,4 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core' import { Component, OnInit } from '@angular/core'
@Component({ @Component({
selector: 'app-not-found', selector: 'app-not-found',
@ -6,8 +6,7 @@ import { Component, OnInit, ViewEncapsulation } from '@angular/core'
styleUrls: ['./not-found.component.scss'], styleUrls: ['./not-found.component.scss'],
host: { host: {
class: 'content-container' class: 'content-container'
}, }
encapsulation: ViewEncapsulation.None
}) })
export class NotFoundComponent implements OnInit { export class NotFoundComponent implements OnInit {
constructor() {} constructor() {}

Some files were not shown because too many files have changed in this diff Show More