diff --git a/.github/workflows/release-workflow.yaml b/.github/workflows/release-workflow.yaml new file mode 100644 index 0000000..c40b688 --- /dev/null +++ b/.github/workflows/release-workflow.yaml @@ -0,0 +1,196 @@ +name: Release Workflow + +on: + push: + branches: + - master + - main + workflow_dispatch: + inputs: + version: + description: 'Version to release (leave empty to use info.xml version)' + required: false + default: '' + +jobs: + release-management: + runs-on: ubuntu-latest + steps: + + - name: Checkout Code + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set app env + run: | + echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV + + - name: Get current version and increment + id: increment_version + run: | + current_version=$(grep -oP '(?<=)[^<]+' appinfo/info.xml) + IFS='.' read -ra version_parts <<< "$current_version" + ((version_parts[2]++)) + new_version="${version_parts[0]}.${version_parts[1]}.${version_parts[2]}" + echo "NEW_VERSION=$new_version" >> $GITHUB_ENV + echo "new_version=$new_version" >> $GITHUB_OUTPUT + + - name: Update version in info.xml + run: | + sed -i "s|.*|${{ env.NEW_VERSION }}|" appinfo/info.xml + + - name: Commit version update + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git commit -am "Bump version to ${{ env.NEW_VERSION }}" + git push + + # Step 1: Prepare the signing certificate and key + - name: Prepare Signing Certificate and Key + run: | + echo "${{ secrets.NEXTCLOUD_SIGNING_CERT }}" > signing-cert.crt + echo "${{ secrets.NEXTCLOUD_SIGNING_KEY }}" > signing-key.key + + # Step 3: Install Node.js dependencies using npm + - name: Install npm dependencies + uses: actions/setup-node@v3 + with: + node-version: '18.x' # Specify Node.js version + + # Step 4: Install PHP extensions + - name: Set up PHP and install extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: zip, gd + + # Step 5: Build the node dependencies + - run: npm ci + + # Step 6: Build the node dependencies + - run: npm run build + + # Step 7: Build composer dependencies + - run: composer i --no-dev + + # Step 8: Copy the files into the package directory + - name: Copy the package files into the package + run: | + mkdir -p package/${{ github.event.repository.name }} + rsync -av --progress \ + --exclude='package' \ + --exclude='.git' \ + --exclude='.github' \ + --exclude='.vscode' \ + --exclude='docker' \ + --exclude='docs' \ + --exclude='node_modules' \ + --exclude='/src' \ + --exclude='test' \ + --exclude='package-lock.json' \ + --exclude='composer.lock' \ + --exclude='composer-setup.php' \ + --exclude='.phpunit.result.cache' \ + --exclude='phpmd.xml' \ + --exclude='signing-key.key' \ + --exclude='package.json' \ + --exclude='composer.json' \ + --exclude='coverage.txt' \ + --exclude='signing-cert.crt' \ + --exclude='docker-compose.yml' \ + --exclude='webpack.config.js' \ + --exclude='.prettierrc' \ + --exclude='psalm.xml' \ + --exclude='phpunit.xml' \ + --exclude='tsconfig.json' \ + --exclude='changelog-ci-config.json' \ + --exclude='jest.config.js' \ + --exclude='.gitattributes' \ + --exclude='.php-cs-fixer.dist.php' \ + --exclude='.gitignore' \ + --exclude='.eslintrc.js' \ + --exclude='stylelint.config.js' \ + --exclude='.babelrc' \ + --exclude='.nvmrc' \ + ./ package/${{ github.event.repository.name }}/ + + # Step 9: Create the TAR.GZ archive + - name: Create Tarball + run: | + cd package && tar -czf ../nextcloud-release.tar.gz ${{ github.event.repository.name }} + + # Step 10: Sign the TAR.GZ file with OpenSSL + - name: Sign the TAR.GZ file with OpenSSL + run: | + openssl dgst -sha512 -sign signing-key.key nextcloud-release.tar.gz | openssl base64 -out nextcloud-release.signature + + # Step 11: Generate Git version information + - name: Git Version + id: version + uses: codacy/git-version@2.7.1 + with: + release-branch: main + + # Step 12: Extract repository description + - name: Extract repository description + id: repo-description + run: | + description=$(jq -r '.description' <(curl -s https://api.github.com/repos/${{ github.repository }})) + echo "REPO_DESCRIPTION=$description" >> $GITHUB_ENV + + # Step 13: Run Changelog CI + - name: Run Changelog CI + if: github.ref == 'refs/heads/main' + uses: saadmk11/changelog-ci@v1.1.2 + with: + release_version: ${{ env.NEW_VERSION }} + config_file: changelog-ci-config.json + + # Step 14: Output the version + - name: Use the version + run: | + echo ${{ steps.version.outputs.version }} + + # Step 15: Copy the package files into the package (this step seems redundant, consider removing) + - name: Copy the package files into the package + run: | + mkdir -p package/${{ github.event.repository.name }} + rsync -av --progress --exclude='package' --exclude='.git' ./ package/${{ github.event.repository.name }}/ + + # Step 18: Create a new release on GitHub + - name: Upload Release + uses: ncipollo/release-action@v1.12.0 + with: + tag: v${{ env.NEW_VERSION }} + name: Release ${{ env.NEW_VERSION }} + draft: false + prerelease: false + + - name: Attach tarball to github release + uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2 + id: attach_to_release + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: nextcloud-release.tar.gz # Corrected spelling + asset_name: ${{ env.APP_NAME }}-${{ env.NEW_VERSION }}.tar.gz + tag: v${{ env.NEW_VERSION }} + overwrite: true + + - name: Upload app to Nextcloud appstore + uses: nextcloud-releases/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.NEXTCLOUD_APPSTORE_TOKEN }} + download_url: https://github.com/${{ github.repository }}/releases/download/v${{ env.NEW_VERSION }}/${{ env.APP_NAME }}-${{ env.NEW_VERSION }}.tar.gz + app_private_key: ${{ secrets.NEXTCLOUD_SIGNING_KEY }} + nightly: false + + - name: Verify version and contents + run: | + echo "App version: ${{ env.NEW_VERSION }}" + echo "Tarball contents:" + tar -tvf nextcloud-release.tar.gz + echo "info.xml contents:" + tar -xOf nextcloud-release.tar.gz ${{ env.APP_NAME }}/appinfo/info.xml diff --git a/.github/workflows/release-workflows.yaml b/.github/workflows/release-workflows.yaml new file mode 100644 index 0000000..38c189d --- /dev/null +++ b/.github/workflows/release-workflows.yaml @@ -0,0 +1,166 @@ +name: Release Workflow + +on: [push] + +jobs: + release-management: + runs-on: ubuntu-latest + steps: + + - name: Set app env + run: | + # Split and keep last + echo "APP_NAME=${GITHUB_REPOSITORY##*/}" >> $GITHUB_ENV + echo "APP_VERSION=${GITHUB_REF##*/}" >> $GITHUB_ENV + + # Step 1: Checkout the code + - name: Checkout Code + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} # Checkout the correct branch name + fetch-depth: 0 # Fetch the whole repo history + + # Step 2: Prepare the signing certificate and key + - name: Prepare Signing Certificate and Key + run: | + echo "${{ secrets.NEXTCLOUD_SIGNING_CERT }}" > signing-cert.crt + echo "${{ secrets.NEXTCLOUD_SIGNING_KEY }}" > signing-key.key + + # Step 3: Install Node.js dependencies using npm + - name: Install npm dependencies + uses: actions/setup-node@v3 + with: + node-version: '18.x' # Specify Node.js version + + # Step 4: Install PHP extensions + - name: Set up PHP and install extensions + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: zip, gd + + # Step 5: Build the node dependencies + - run: npm ci + + # Step 6: Build the node dependencies + - run: npm run build + + # Step 7: Build composer dependencies + - run: composer i --no-dev + + # Step 8: Copy the files into the package directory, excluding .git and package itself + - name: Copy the package files into the package + run: | + mkdir -p package/zaakafhandelapp + rsync -av --progress \ + --exclude='package' \ + --exclude='.git' \ + --exclude='.github' \ + --exclude='.vscode' \ + --exclude='docker' \ + --exclude='docs' \ + --exclude='node_modules' \ + --exclude='src' \ + --exclude='test' \ + --exclude='package-lock.json' \ + --exclude='composer.lock' \ + --exclude='composer-setup.php' \ + --exclude='.phpunit.result.cache' \ + --exclude='phpmd.xml' \ + --exclude='signing-key.key' \ + --exclude='package.json' \ + --exclude='composer.json' \ + --exclude='coverage.txt' \ + --exclude='signing-cert.crt' \ + --exclude='docker-compose.yml' \ + --exclude='webpack.config.js' \ + --exclude='.prettierrc' \ + --exclude='psalm.xml' \ + --exclude='phpunit.xml' \ + --exclude='tsconfig.json' \ + --exclude='changelog-ci-config.json' \ + --exclude='jest.config.js' \ + --exclude='.gitattributes' \ + --exclude='.php-cs-fixer.dist.php' \ + --exclude='.gitignore' \ + --exclude='.eslintrc.js' \ + --exclude='stylelint.config.js' \ + --exclude='.babelrc' \ + --exclude='.nvmrc' \ + ./ package/zaakafhandelapp/ + + # Step 9: Create the TAR.GZ archive with code in zaakafhandelapp directory + - name: Create Tarball + run: | + cd package && tar -czf ../nexcloud-release.tar.gz zaakafhandelapp + + # Step 10: Sign the TAR.GZ file with OpenSSL + - name: Sign the TAR.GZ file with OpenSSL + run: | + openssl dgst -sha512 -sign signing-key.key nexcloud-release.tar.gz | openssl base64 -out nexcloud-release.signature + + # Step 11: Generate Git version information + - name: Git Version + id: version + uses: codacy/git-version@2.7.1 + with: + release-branch: main + + # Step 12: Extract repository description + - name: Extract repository description + id: repo-description + run: | + description=$(jq -r '.description' <(curl -s https://api.github.com/repos/${{ github.repository }})) + echo "REPO_DESCRIPTION=$description" >> $GITHUB_ENV + + # Step 13: Run Changelog CI + - name: Run Changelog CI + if: github.ref == 'refs/heads/master' + uses: saadmk11/changelog-ci@v1.1.2 + with: + release_version: ${{ steps.version.outputs.version }} + config_file: changelog-ci-config.json + + # Step 14: Output the version + - name: Use the version + run: | + echo ${{ steps.version.outputs.version }} + + # Step 15: Copy the files into the package directory, excluding .git and package itself + - name: Copy the package files into the package + run: | + mkdir -p package/zaakafhandelapp + rsync -av --progress --exclude='package' --exclude='.git' ./ package/zaakafhandelapp/ + + # Step 18: Create a new release on GitHub + - name: Upload Release + uses: ncipollo/release-action@v1.12.0 + with: + artifacts: | + LICENSE.md + nexcloud-release.tar.gz + nexcloud-release.signature + zaakafhandelapp-build.zip + zaakafhandelapp-build.tar.gz + token: ${{ secrets.GITHUB_TOKEN }} + tag: ${{ steps.version.outputs.version }} + + - name: Attach tarball to github release + uses: svenstaro/upload-release-action@04733e069f2d7f7f0b4aebc4fbdbce8613b03ccd # v2 + id: attach_to_release + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: nexcloud-release.tar.gz + asset_name: ${{ env.APP_NAME }}-${{ env.APP_VERSION }}.tar.gz + tag: ${{ github.ref }} + overwrite: true + + - name: Upload app to Nextcloud appstore + uses: nextcloud-releases/nextcloud-appstore-push-action@a011fe619bcf6e77ddebc96f9908e1af4071b9c1 # v1 + with: + app_name: ${{ env.APP_NAME }} + appstore_token: ${{ secrets.NEXTCLOUD_APPSTORE_TOKEN }} + download_url: ${{ steps.attach_to_release.outputs.browser_download_url }} + app_private_key: ${{ secrets.NEXTCLOUD_SIGNING_KEY }} + + diff --git a/.nextcloud/certificates/zaakafhandelapp.csr b/.nextcloud/certificates/zaakafhandelapp.csr new file mode 100644 index 0000000..118af1f --- /dev/null +++ b/.nextcloud/certificates/zaakafhandelapp.csr @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIEXzCCAkcCAQAwGjEYMBYGA1UEAwwPemFha2FmaGFuZGVsYXBwMIICIjANBgkq +hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnI2P93yLIINt4aOwwLO6Jn6CvbXhbbnI +ri4UieBwnGq0xDNmb//sDB+FOZOqOCqdw8Zj38ALck+W5P+4OfkPuUAjJIbGu23L +V100u+YD3m0jfkh2FSOEtqNcyLYPebW5xPdqcGXDinaxqsjqCYGgVZIyeaSTHPpv +xHEDccrPI0H0uHi1NOQH2uDTnFfzqKweFXUNI8xI9z7PAnyLnUBCLsXEe4NABpqL +pt4cwWVe/dTchYF7mr2xq4oGvmoMub09oSoaP6vzkTbr7CErew8GQ+cgJs3UfiEk +Cjgl2GT5Lk+6Fdd1hBsbHaoTbETky69VXrN57f8qiePsMMr9r4zmG30f/ESytPip +J1UjMiFmQGPrI4h6+9Vabfak6MAyJucFUwO25WsSR4X0XQUhFVpHww+WbpOa87wl +CRSutySL7tRy7vidaMwUl0Ayhyfc99lnEHwOMxJxCAyIddcC5NIv3LgbDbZ1MW9/ +x7LUDDPmu8kE8QB0anKpmxA/oa44zJqifeRo6slT/A+8PvagLaXaC08jgKixbfWr +orz+RZjpHJJ0U88jR7IiB06iki5VCxxIXpq8APRtMinyrOvbOfGKFWGClm7wefiY +w8Wyv2Dk4BH7T8i7OO+jZv7ZuYRqQ0iTpMiJR2NPBxz2FaTPBRW/lH3gvT/BDdpP +PUfvh7DQiMECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4ICAQB9pQt94oWp7h4R3GIY +1VRqqA441ETEf7WQF5+650fvrmgfAfi4ibtnYxe6mJVVUZbFabnaxzDFMW5D/D2w +j4pvX3FMaO/Bns2AgNKLfIS7Z4wG6FEPaat2sL/rCyZFR4TK+vhq0d/Iz7lb/zNs +WRZC3mEawsu0BEmR5fcckSvAM7U3D7zv+zOW/siYCpyWdhnQ7UBquIEwpQCCpzvI +KuFZIgCmqMOh3H3TPyvB/f+esn8i6pzSj4r8hKq+EHkuDoSUc8nRtO9E5SRs8lCL +yxJnbVkrJZE5vJDycnjoKBcVTLAi8S6YfAcSqV0nfawOs5lV2Del+m4oapvjG1og +8bwN3HEmZiyQJ1GF7SCQsos6hncJUed+5iIrdyGnfzq8K2AFkBoCsqZfCvUoSSt7 +UmJKVP1ZjQP225P178flK+3IVeVPtUD6QbMPRLlgQrh1y+rY4e7Pnk45trOrIICU +KQcbl65TWiaZOgsbll3t+kvXw8N/7fgeeyNe26IgQGvJCSJfMiLKiezNdFkIucsa +NsMiSvln4ims3+ZNicShV0qBG+rcFSsuhM+JpM0+k8tb8iyHeKAhgNWw6PodqIRv +AFak6fR0uK0O/roI+VTDy2SXYE2Dbn4yWEBKVovN8zq2he8rmEVNiyptKKFw03s2 +3StYdcaZetHMu9a8kQQ1vAwL4g== +-----END CERTIFICATE REQUEST----- diff --git a/.nvmrc b/.nvmrc index 209e3ef..12cf442 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20 +20 diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 91fc1d9..e753412 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -1,19 +1,19 @@ -getFinder() - ->notPath('build') - ->notPath('l10n') - ->notPath('node_modules') - ->notPath('src') - ->notPath('vendor') - ->in(__DIR__); - -return $config; +getFinder() + ->notPath('build') + ->notPath('l10n') + ->notPath('node_modules') + ->notPath('src') + ->notPath('vendor') + ->in(__DIR__); + +return $config; diff --git a/.prettierrc b/.prettierrc index cff2845..201d202 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,38 +1,38 @@ -{ - "overrides": [ - { - "files": ["*.json"], - "options": { - "parser": "json", - "printWidth": 120, - "tabWidth": 2 - } - }, - { - "files": ["*.ts", "*.tsx"], - "options": { - "parser": "typescript", - "printWidth": 120, - "trailingComma": "all", - "tabWidth": 2, - "singleQuote": false - } - }, - { - "files": ["*.css", "*.scss"], - "options": { - "parser": "css", - "tabWidth": 2 - } - }, - { - "files": ["conduction.css"], - "options": { - "parser": "css", - "trailingComma": "all", - "tabWidth": 2, - "printWidth": 150 - } - } - ] -} +{ + "overrides": [ + { + "files": ["*.json"], + "options": { + "parser": "json", + "printWidth": 120, + "tabWidth": 2 + } + }, + { + "files": ["*.ts", "*.tsx"], + "options": { + "parser": "typescript", + "printWidth": 120, + "trailingComma": "all", + "tabWidth": 2, + "singleQuote": false + } + }, + { + "files": ["*.css", "*.scss"], + "options": { + "parser": "css", + "tabWidth": 2 + } + }, + { + "files": ["conduction.css"], + "options": { + "parser": "css", + "trailingComma": "all", + "tabWidth": 2, + "printWidth": 150 + } + } + ] +} diff --git a/README.md b/README.md index 0d1c0e2..cff119d 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,67 @@ -# Zaak Afhandel App - -Deze nextcloud app voorziet in een klein doch volledige zaak afhandel applicatie - -## Features - -1. Zaakafhaneling -2. Toewijzen van taken aan medewerkers en klanten -3. Versturen van berichten -4. Inzien en aanpassen van klant gegevens - - -## Installatie - -Volg voor het het lokaal installeren van Nextcloud de handleiding op https://cloud.nextcloud.com/s/iyNGp8ryWxc7Efa?dir=undefined&path=%2F1%20Setting%20up%20a%20development%20environment%2FTutorial%20for%20Windows&openfile=7087340 - -!let op! Installatie via de Nextcloud handleiding plaats de code in je ubuntu vm (wml) waarmee die niet vanzelf in windows file explorer terugkomt. Wil je je WSL bekijken via file explorer tik dan \\wsl$ in de adresbalk - -1. Navigeer binnen de Nextcloud folder op je wsl naar de workspace/server/apps-extra map, als je de command line interface nog open hebt staan kan dat via cd workspace/server/apps-extra -2. Clone deze repository naar binnen via het commando `git clone https://github.com/ConductionNL/zaakafhandelapp` -3. Draai vervolgens de commando's `npm i` en daarna `npm run dev` via de command line interface. - - ![appsOverview.png](img/appsOverview.png) - -# Frontend veranderen -Om de frontend te veranderen verander je de content in de .vue bestanden. -Elke keer als je iets hebt gewijzigd in en .vue bestand dan moet je `npm run dev` draaien. Een makkelijkere manier om dit bij te houden is `npm run watch` dit commando kijkt naar veranderingen in de .vue bestanden en zet dit meteen door. -Je moet wel elke keer als je iets veranderd verversen - - -## Code bekijken - -\\wsl.localhost\Ubuntu-20.04\home\user\nextcloud-docker-dev\workspace\server\apps-extra - -## Linting en code validatie - -```cli -npm run lint -``` - -## Upen - -`docker-compose up nextcloud proxy` - -Clone de dsonextcloud app in de folder C:\path...\nextcloud-docker-dev\workspace\server\apps-extra en start de Nextcloud server op. -Open ondertussen een terminal in de dsonextcloud folder en run `npm i` en daarna `npm run dev`. -Als de server gestart is log dan in met het standaard admin account (name: admin, psw: admin). - -Ga naar apps - -![profielOverview](img/profielOverview.png) - -en schakel de Zaak Afhandel App in. - -![zaaApp](img/zaaApp.png) - -Wacht totdat de app zichtbaar is in de navigatie balk en klik op de app. - -![navigationBarZaa](img/navigationBarZaa.png) - - - -## Documentatie -[Icons](https://pictogrammers.com/library/mdi/) - -[Layout](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html) - -[Componenten](https://nextcloud-vue-components.netlify.app/) +# Zaak Afhandel App + +Deze nextcloud app voorziet in een klein doch volledige zaak afhandel applicatie + +## Features + +1. Zaakafhaneling +2. Toewijzen van taken aan medewerkers en klanten +3. Versturen van berichten +4. Inzien en aanpassen van klant gegevens + + +## Installatie + +Volg voor het het lokaal installeren van Nextcloud de handleiding op https://cloud.nextcloud.com/s/iyNGp8ryWxc7Efa?dir=undefined&path=%2F1%20Setting%20up%20a%20development%20environment%2FTutorial%20for%20Windows&openfile=7087340 + +!let op! Installatie via de Nextcloud handleiding plaats de code in je ubuntu vm (wml) waarmee die niet vanzelf in windows file explorer terugkomt. Wil je je WSL bekijken via file explorer tik dan \\wsl$ in de adresbalk + +1. Navigeer binnen de Nextcloud folder op je wsl naar de workspace/server/apps-extra map, als je de command line interface nog open hebt staan kan dat via cd workspace/server/apps-extra +2. Clone deze repository naar binnen via het commando `git clone https://github.com/ConductionNL/zaakafhandelapp` +3. Draai vervolgens de commando's `npm i` en daarna `npm run dev` via de command line interface. + + ![appsOverview.png](img/appsOverview.png) + +# Frontend veranderen +Om de frontend te veranderen verander je de content in de .vue bestanden. +Elke keer als je iets hebt gewijzigd in en .vue bestand dan moet je `npm run dev` draaien. Een makkelijkere manier om dit bij te houden is `npm run watch` dit commando kijkt naar veranderingen in de .vue bestanden en zet dit meteen door. +Je moet wel elke keer als je iets veranderd verversen + + +## Code bekijken + +\\wsl.localhost\Ubuntu-20.04\home\user\nextcloud-docker-dev\workspace\server\apps-extra + +## Linting en code validatie + +```cli +npm run lint +``` + +## Upen + +`docker-compose up nextcloud proxy` + +Clone de dsonextcloud app in de folder C:\path...\nextcloud-docker-dev\workspace\server\apps-extra en start de Nextcloud server op. +Open ondertussen een terminal in de dsonextcloud folder en run `npm i` en daarna `npm run dev`. +Als de server gestart is log dan in met het standaard admin account (name: admin, psw: admin). + +Ga naar apps + +![profielOverview](img/profielOverview.png) + +en schakel de Zaak Afhandel App in. + +![zaaApp](img/zaaApp.png) + +Wacht totdat de app zichtbaar is in de navigatie balk en klik op de app. + +![navigationBarZaa](img/navigationBarZaa.png) + +## API +- https://vng-realisatie.github.io/gemma-zaken/standaard/catalogi/redoc-1.3.1#tag/zaaktypen/operation/zaaktype_create + +## Documentatie +- [Icons](https://pictogrammers.com/library/mdi/) +- [Layout](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html)- +- [Componenten](https://nextcloud-vue-components.netlify.app/) diff --git a/appinfo/info.xml b/appinfo/info.xml index 60f28d7..823b375 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -2,26 +2,53 @@ zaakafhandelapp - - Zaak Afhandel App - The Zaak Afhandel App (ZAA), or in english Case Managment App is a nextcloud app that provid a basic case Managment funtionality - This is a the ZAA (Zaak Afhandel App) in english Case Handling App that is made by ConductionNL - 1.0.0 - eupl 1.2 - Conduction + Zaak Afhandel App + This is a the ZAA (Zaak Afhandel App) in english Case Handling App that is made by ConductionN + + 0.1.1 + agpl + Conduction ZaakAfhandelApp - dashboard + organisation + https://github.com/ConductionNL/zaakafhandelapp https://github.com/ConductionNL/zaakafhandelapp/issues - - + https://github.com/ConductionNL/zaakafhandelapp.git + + + pgsql + sqlite + mysql + + + zaakafhandelapp Zaak Afhandel App zaakafhandelapp.dashboard.page - app.svg - 8 + + + OCA\ZaakAfhandelApp\Settings\ZaakAfhandelAppAdmin + OCA\ZaakAfhandelApp\Sections\ZaakAfhandelAppAdmin + diff --git a/appinfo/routes.php b/appinfo/routes.php index 2e31792..b1cc408 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -1,42 +1,45 @@ - [ - // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/zaken/redoc-1.5.1 - 'zaken' => ['url' => 'api/zrc/zaken'], - 'resultaten' => ['url' => 'api/zrc/resultaten'], - 'rollen' => ['url' => 'api/zrc/rollen'], - 'statussen' => ['url' => 'api/zrc/statussen'], - 'zaakinformatieobjecten' => ['url' => 'api/zrc/zaakinformatieobjecten'], - 'zaakobjecten' => ['url' => 'api/zrc/zaakobjecten'], - 'zaakbesluiten' => ['url' => 'api/zrc/zaken/{zaak_uuid}/besluiten'], - 'zaakeigenschappen' => ['url' => 'api/zrc/zaken/{zaak_uuid}/eigenschappen'], - 'zaakaudittrail' => ['url' => 'api/zrc/zaken/{zaak_uuid}/audit_trail'], - // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/catalogi/redoc-1.3.1 - 'zaakTypen' => ['url' => 'api/ztc'], - // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/documenten/redoc-1.5.0 - 'documenten' => ['url' => 'api/drc'], - // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/besluiten/redoc-1.0.2 - 'besluiten' => ['url' => 'api/brc'], - // Conform ??? - 'zaakTypen' => ['url' => 'api/ztc/zaaktypen'], - // Conform ??? - 'taken' => ['url' => 'api/taken'], - 'klanten' => ['url' => 'api/klanten'], - 'berichten' => ['url' => 'api/berichten'], - ], - 'routes' => [ - // Page routes - ['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'], - ['name' => 'configuration#index', 'url' => '/api/configuration', 'verb' => 'GET'], - ['name' => 'configuration#create', 'url' => '/api/configuration', 'verb' => 'POST'], - ['name' => 'zaken#page', 'url' => '/zaken', 'verb' => 'GET'], - ['name' => 'rollen#page', 'url' => '/rollen', 'verb' => 'GET'], - ['name' => 'statussen#page', 'url' => '/statussen', 'verb' => 'GET'], - ['name' => 'zaakinformatieobjecten#page', 'url' => '/zaakinformatieobjecten', 'verb' => 'GET'], - ['name' => 'zaakTypen#page','url' => '/zaak_typen', 'verb' => 'GET'], - ['name' => 'taken#page','url' => '/taken', 'verb' => 'GET'], - ['name' => 'klanten#page','url' => '/klanten', 'verb' => 'GET'], - ['name' => 'berichten#index','url' => '/berichten', 'verb' => 'GET'], - ] -]; + [ + // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/zaken/redoc-1.5.1 + 'zaken' => ['url' => 'api/zrc/zaken'], + 'resultaten' => ['url' => 'api/zrc/resultaten'], + 'rollen' => ['url' => 'api/zrc/rollen'], + 'statussen' => ['url' => 'api/zrc/statussen'], + 'zaakinformatieobjecten' => ['url' => 'api/zrc/zaakinformatieobjecten'], + 'zaakobjecten' => ['url' => 'api/zrc/zaakobjecten'], + 'zaakbesluiten' => ['url' => 'api/zrc/zaken/{zaak_uuid}/besluiten'], + 'zaakeigenschappen' => ['url' => 'api/zrc/zaken/{zaak_uuid}/eigenschappen'], + 'zaakaudittrail' => ['url' => 'api/zrc/zaken/{zaak_uuid}/audit_trail'], + // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/catalogi/redoc-1.3.1 + 'zaakTypen' => ['url' => 'api/ztc'], + // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/documenten/redoc-1.5.0 + 'documenten' => ['url' => 'api/drc'], + // Conform https://vng-realisatie.github.io/gemma-zaken/standaard/besluiten/redoc-1.0.2 + 'besluiten' => ['url' => 'api/brc'], + // Conform ??? + 'zaakTypen' => ['url' => 'api/ztc/zaaktypen'], + // Conform ??? + 'taken' => ['url' => 'api/taken'], + 'klanten' => ['url' => 'api/klanten'], + 'berichten' => ['url' => 'api/berichten'], + ], + 'routes' => [ + // Page routes + ['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'], + ['name' => 'configuration#index', 'url' => '/api/configuration', 'verb' => 'GET'], + ['name' => 'configuration#create', 'url' => '/api/configuration', 'verb' => 'POST'], + ['name' => 'zaken#page', 'url' => '/zaken', 'verb' => 'GET'], + ['name' => 'rollen#page', 'url' => '/rollen', 'verb' => 'GET'], + ['name' => 'statussen#page', 'url' => '/statussen', 'verb' => 'GET'], + ['name' => 'zaakinformatieobjecten#page', 'url' => '/zaakinformatieobjecten', 'verb' => 'GET'], + ['name' => 'zaakTypen#page','url' => '/zaak_typen', 'verb' => 'GET'], + ['name' => 'taken#page','url' => '/taken', 'verb' => 'GET'], + ['name' => 'klanten#page','url' => '/klanten', 'verb' => 'GET'], + ['name' => 'berichten#index','url' => '/berichten', 'verb' => 'GET'], + // user Settings + ['name' => 'settings#index','url' => '/settings', 'verb' => 'GET'], + ['name' => 'settings#create', 'url' => '/settings', 'verb' => 'POST'], + ] +]; diff --git a/composer.json b/composer.json index 4ccd5c7..0be575b 100644 --- a/composer.json +++ b/composer.json @@ -1,59 +1,65 @@ -{ - "name": "nextcloud/zaakafhandelapp", - "description": "This nextcloud app provid a basic zaak afhandel component for dutch governemental institutions", - "license": "AGPL-3.0-or-later", - "authors": [ - { - "name": "Conduction b.v.", - "email": "info@conduction.nl", - "homepage": "" - }, - { - "name": "Remko Huisman (Conduction)", - "email": "remko@conduction.nl", - "homepage": "" - }, - { - "name": "Ruben van der Linde (Conduction)", - "email": "ruben@conduction.nl", - "homepage": "" - } - ], - "autoload": { - "psr-4": { - "OCA\\ZaakAfhandelApp\\": "lib/" - } - }, - "scripts": { - "post-install-cmd": [ - "@composer bin all install --ansi" - ], - "post-update-cmd": [ - "@composer bin all update --ansi" - ], - "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './vendor-bin/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l", - "cs:check": "php-cs-fixer fix --dry-run --diff", - "cs:fix": "php-cs-fixer fix", - "psalm": "psalm --threads=1 --no-cache", - "test:unit": "phpunit tests -c tests/phpunit.xml --colors=always --fail-on-warning --fail-on-risky", - "openapi": "generate-spec" - }, - "require": { - "bamarni/composer-bin-plugin": "^1.8", - "php": "^8.1" - }, - "require-dev": { - "nextcloud/ocp": "dev-stable29", - "roave/security-advisories": "dev-latest" - }, - "config": { - "allow-plugins": { - "bamarni/composer-bin-plugin": true - }, - "optimize-autoloader": true, - "sort-packages": true, - "platform": { - "php": "8.1" - } - } -} +{ + "name": "nextcloud/zaakafhandelapp", + "description": "This nextcloud app provid a basic zaak afhandel component for dutch governemental institutions", + "license": "AGPL-3.0-or-later", + "authors": [ + { + "name": "Conduction b.v.", + "email": "info@conduction.nl", + "homepage": "https://conduction.nl" + }, + { + "name": "Remko Huisman (Conduction)", + "email": "remko@conduction.nl", + "homepage": "https://conduction.nl" + }, + { + "name": "Ruben van der Linde (Conduction)", + "email": "ruben@conduction.nl", + "homepage": "https://conduction.nl" + } + ], + "autoload": { + "psr-4": { + "OCA\\ZaakAfhandelApp\\": "lib/" + } + }, + "scripts": { + "post-install-cmd": [ + "@composer bin all install --ansi" + ], + "post-update-cmd": [ + "@composer bin all update --ansi" + ], + "lint": "find . -name \\*.php -not -path './vendor/*' -not -path './vendor-bin/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l", + "cs:check": "php-cs-fixer fix --dry-run --diff", + "cs:fix": "php-cs-fixer fix", + "psalm": "psalm --threads=1 --no-cache", + "test:unit": "phpunit tests -c tests/phpunit.xml --colors=always --fail-on-warning --fail-on-risky", + "openapi": "generate-spec" + }, + "require": { + "php": "^8.1", + "adbario/php-dot-notation": "^3.3.0", + "bamarni/composer-bin-plugin": "^1.8", + "elasticsearch/elasticsearch": "^v8.14.0", + "adbario/php-dot-notation": "^3.3.0", + "guzzlehttp/guzzle": "^7.0", + "symfony/uid": "^6.4" + }, + "require-dev": { + "nextcloud/ocp": "dev-stable29", + "roave/security-advisories": "dev-latest" + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true, + "php-http/discovery": true + }, + "optimize-autoloader": true, + "sort-packages": true, + "platform": { + "php": "8.1" + } + } +} diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 5e2733b..eb53613 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -1,36 +1,36 @@ - [ - "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "batchID" => "f7eebefe-52e6-4b60-a80a-47d6f1cbd5bf", - "aanmaakDatum" => "2023-07-08T12:00:00Z", - "berichtLeverancierID" => "12345678901234567890", - "berichtID" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "berichtType" => "Type1", - "publicatieDatum" => "2023-07-10T12:00:00Z", - "onderwerp" => "Onderwerp 1", - "berichttekst" => "Dit is de tekst van bericht 1.", - "referentie" => "Ref1", - "gebruikerID" => "987654321", - "soortGebruiker" => "Burger", - "inhoud" => "VGhpcyBpcyBhIHRlc3QgcGRmIGZpbGUu", - "bijlageType" => "Pdf", - "omschrijving" => "Omschrijving voor bijlage 1", - "volgorde" => "1" - ], - "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ - "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "batchID" => "c9d3a2e9-bb4e-4212-a55c-9a8e8376d5c5", - "aanmaakDatum" => "2023-07-09T12:00:00Z", - "berichtLeverancierID" => "22345678901234567890", - "berichtID" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "berichtType" => "Type2", - "publicatieDatum" => "2023-07-11T12:00:00Z", - "onderwerp" => "Onderwerp 2", - "berichttekst" => "Dit is de tekst van bericht 2.", - "referentie" => "Ref2", - "gebruikerID" => "876543210", - "soortGebruiker" => "Burger", - "inhoud" => "VGhpcyBpcyBhbm90aGVyIHRlc3QgcGRmIGZpbGUu", - "bijlageType" => "Pdf", - "omschrijving" => "Omschrijving voor bijlage 2", - "volgorde" => "2" - ], - "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ - "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "batchID" => "a7d3b4e5-d64f-499a-96e5-c2bf9f5c7d2c", - "aanmaakDatum" => "2023-07-10T12:00:00Z", - "berichtLeverancierID" => "32345678901234567890", - "berichtID" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "berichtType" => "Type3", - "publicatieDatum" => "2023-07-12T12:00:00Z", - "onderwerp" => "Onderwerp 3", - "berichttekst" => "Dit is de tekst van bericht 3.", - "referentie" => "Ref3", - "gebruikerID" => "765432109", - "soortGebruiker" => "Burger", - "inhoud" => "VGhpcyBpcyB5ZXQgYW5vdGhlciB0ZXN0IHBkZiBmaWxlLg==", - "bijlageType" => "Pdf", - "omschrijving" => "Omschrijving voor bijlage 3", - "volgorde" => "3" - ], - "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ - "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "batchID" => "b7c3e5f9-ec2f-4dbb-b602-e7af1f7e5c4d", - "aanmaakDatum" => "2023-07-11T12:00:00Z", - "berichtLeverancierID" => "42345678901234567890", - "berichtID" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "berichtType" => "Type4", - "publicatieDatum" => "2023-07-13T12:00:00Z", - "onderwerp" => "Onderwerp 4", - "berichttekst" => "Dit is de tekst van bericht 4.", - "referentie" => "Ref4", - "gebruikerID" => "654321098", - "soortGebruiker" => "Burger", - "inhoud" => "VGhpcyBpcyBhbm90aGVyIHRlc3QgcGRmIGZpbGUu", - "bijlageType" => "Pdf", - "omschrijving" => "Omschrijving voor bijlage 4", - "volgorde" => "4" - ] - ]; - public function __construct( $appName, IRequest $request, @@ -163,10 +88,18 @@ public function create(CallService $callService): JSONResponse { // get post from requests $body = $this->request->getParams(); + $body['id'] = $this->get_guid(); //@todo remove this hotfic (or actually horror fix) $results = $callService->create(source: 'klanten', endpoint: 'taken', data: $body); return new JSONResponse($results); } + function get_guid() { + $data = PHP_MAJOR_VERSION < 7 ? openssl_random_pseudo_bytes(16) : random_bytes(16); + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Set version to 0100 + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Set bits 6-7 to 10 + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); + } + /** * Update an object * diff --git a/lib/Controller/DashboardController.php b/lib/Controller/DashboardController.php index dabcc32..d9c9112 100644 --- a/lib/Controller/DashboardController.php +++ b/lib/Controller/DashboardController.php @@ -1,136 +1,136 @@ - [ - "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "name" => "Github", - "summary" => "summary for one" - ], - "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ - "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "name" => "Gitlab", - "summary" => "summary for two" - ], - "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ - "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "name" => "Woo", - "summary" => "summary for two" - ], - "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ - "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "name" => "Decat", - "summary" => "summary for two" - ] - ]; - - public function __construct( - $appName, - IRequest $request, - private readonly IAppConfig $config - ) - { - parent::__construct($appName, $request); - } - - /** - * This returns the template of the main app's page - * It adds some data to the template (app version) - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function page(): TemplateResponse - { - return new TemplateResponse( - //Application::APP_ID, - 'zaakafhandelapp', - 'index', - [] - ); - } - - - /** - * Return (and serach) all objects - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function index(): JSONResponse - { - $results = ["results" => self::TEST_ARRAY]; - return new JSONResponse($results); - } - - /** - * Read a single object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function show(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - - /** - * Creatue an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function create(): JSONResponse - { - // get post from requests - return new JSONResponse([]); - } - - /** - * Update an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function update(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - /** - * Delate an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function destroy(string $id): JSONResponse - { - return new JSONResponse([]); - } - -} + [ + "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", + "name" => "Github", + "summary" => "summary for one" + ], + "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ + "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", + "name" => "Gitlab", + "summary" => "summary for two" + ], + "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ + "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", + "name" => "Woo", + "summary" => "summary for two" + ], + "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ + "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", + "name" => "Decat", + "summary" => "summary for two" + ] + ]; + + public function __construct( + $appName, + IRequest $request, + private readonly IAppConfig $config + ) + { + parent::__construct($appName, $request); + } + + /** + * This returns the template of the main app's page + * It adds some data to the template (app version) + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return TemplateResponse + */ + public function page(): TemplateResponse + { + return new TemplateResponse( + //Application::APP_ID, + 'zaakafhandelapp', + 'index', + [] + ); + } + + + /** + * Return (and serach) all objects + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function index(): JSONResponse + { + $results = ["results" => self::TEST_ARRAY]; + return new JSONResponse($results); + } + + /** + * Read a single object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function show(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + + /** + * Creatue an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function create(): JSONResponse + { + // get post from requests + return new JSONResponse([]); + } + + /** + * Update an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function update(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + /** + * Delate an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function destroy(string $id): JSONResponse + { + return new JSONResponse([]); + } + +} diff --git a/lib/Controller/DocumentenController.php b/lib/Controller/DocumentenController.php index 161323f..76f0fb5 100644 --- a/lib/Controller/DocumentenController.php +++ b/lib/Controller/DocumentenController.php @@ -1,122 +1,122 @@ -config = $config; - } - - /** - * This returns the template of the main app's page - * It adds some data to the template (app version) - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function page(): TemplateResponse - { - return new TemplateResponse( - //Application::APP_ID, - 'zaakafhandelapp', - 'index', - [] - ); - } - - - /** - * Return (and serach) all objects - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function index(): JSONResponse - { - $results = ["results" => self::TEST_ARRAY]; - return new JSONResponse($results); - } - - /** - * Read a single object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function show(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - - /** - * Creatue an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function create(): JSONResponse - { - // get post from requests - return new JSONResponse([]); - } - - /** - * Update an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function update(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - /** - * Delate an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function destroy(string $id): JSONResponse - { - return new JSONResponse([]); - } -} +config = $config; + } + + /** + * This returns the template of the main app's page + * It adds some data to the template (app version) + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return TemplateResponse + */ + public function page(): TemplateResponse + { + return new TemplateResponse( + //Application::APP_ID, + 'zaakafhandelapp', + 'index', + [] + ); + } + + + /** + * Return (and serach) all objects + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function index(): JSONResponse + { + $results = ["results" => self::TEST_ARRAY]; + return new JSONResponse($results); + } + + /** + * Read a single object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function show(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + + /** + * Creatue an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function create(): JSONResponse + { + // get post from requests + return new JSONResponse([]); + } + + /** + * Update an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function update(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + /** + * Delate an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function destroy(string $id): JSONResponse + { + return new JSONResponse([]); + } +} diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php new file mode 100644 index 0000000..e6c57ba --- /dev/null +++ b/lib/Controller/SettingsController.php @@ -0,0 +1,128 @@ +objectService->getOpenRegisters(); + if ($openRegisters !== null) { + $data['openRegisters'] = true; + $data['availableRegisters'] = $openRegisters->getRegisters(); + } + + // Define the default values for the object types + $defaults = [ + 'berichten_source' => 'internal', + 'berichten_schema' => '', + 'berichten_register' => '', + 'besluiten_source' => 'internal', + 'besluiten_schema' => '', + 'besluiten_register' => '', + 'documenten_source' => 'internal', + 'documenten_schema' => '', + 'documenten_register' => '', + 'klanten_source' => 'internal', + 'klanten_schema' => '', + 'klanten_register' => '', + 'resultaten_source' => 'internal', + 'resultaten_schema' => '', + 'resultaten_register' => '', + 'taken_source' => 'internal', + 'taken_schema' => '', + 'taken_register' => '', + 'informatieobjecten_source' => 'internal', + 'informatieobjecten_schema' => '', + 'informatieobjecten_register' => '', + 'organisaties_source' => 'internal', + 'organisaties_schema' => '', + 'organisaties_register' => '', + 'personen_source' => 'internal', + 'personen_schema' => '', + 'personen_register' => '', + 'themas_source' => 'internal', + 'themas_schema' => '', + 'themas_register' => '' + ]; + + // Get the current values for the object types from the configuration + try { + foreach ($defaults as $key => $value) { + $data[$key] = $this->config->getValueString($this->appName, $key, $value); + } + return new JSONResponse($data); + } catch (\Exception $e) { + return new JSONResponse(['error' => $e->getMessage()], 500); + } + } + + /** + * Handle the post request to update settings. + * + * @return JSONResponse JSON response containing the updated settings + * + * @NoCSRFRequired + */ + public function create(): JSONResponse + { + // Get all parameters from the request + $data = $this->request->getParams(); + + try { + // Update each setting in the configuration + foreach ($data as $key => $value) { + $this->config->setValueString($this->appName, $key, $value); + // Retrieve the updated value to confirm the change + $data[$key] = $this->config->getValueString($this->appName, $key); + } + return new JSONResponse($data); + } catch (\Exception $e) { + return new JSONResponse(['error' => $e->getMessage()], 500); + } + } +} diff --git a/lib/Controller/TakenController.php b/lib/Controller/TakenController.php index 00dfe1c..c6468c4 100644 --- a/lib/Controller/TakenController.php +++ b/lib/Controller/TakenController.php @@ -12,49 +12,6 @@ class TakenController extends Controller { - const TEST_ARRAY = [ - "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f" => [ - "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "title" => "Onderzoek naar Markttrends", - "zaak" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "type" => "Onderzoek", - "status" => "open", - "onderwerp" => "Analyse van de huidige markttrends en voorspellingen voor het komende jaar.", - "toelichting" => "Dit onderzoek richt zich op het analyseren van de huidige markttrends in de technologie-sector. Het bevat gedetailleerde gegevens en grafieken die de groei en dalingen in verschillende sub-sectoren weergeven, evenals voorspellingen voor de komende 12 maanden.", - "actie" => "Verzamelen van gegevens, opstellen van rapporten, presenteren aan het management." - ], - "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ - "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "title" => "Ontwikkeling van Nieuw Product", - "zaak" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "type" => "Ontwikkeling", - "status" => "ingediend", - "onderwerp" => "Concept en ontwikkeling van een nieuw innovatief product voor de consumentenmarkt.", - "toelichting" => "Dit project omvat de conceptfase en de vroege ontwikkeling van een nieuw product dat gericht is op het verbeteren van de consumentenervaring in de smart home sector. Het omvat marktonderzoek, productontwerp en het ontwikkelen van een prototype.", - "actie" => "Uitvoeren van marktonderzoek, samenwerken met het designteam, ontwikkelen van een prototype, testen van het product." - ], - "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ - "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "title" => "Interne Audit", - "zaak" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "type" => "Audit", - "status" => "verwerkt", - "onderwerp" => "Uitvoering van een interne audit om de naleving van kwaliteitsnormen te controleren.", - "toelichting" => "Deze taak omvat het uitvoeren van een gedetailleerde interne audit van de bedrijfsprocessen om te controleren of alle afdelingen voldoen aan de vastgestelde kwaliteitsnormen. De bevindingen worden gedocumenteerd en er worden aanbevelingen gedaan voor verbeteringen.", - "actie" => "Voorbereiden van auditchecklist, uitvoeren van audits, rapporteren van bevindingen, aanbevelen van verbeteringen." - ], - "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ - "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "title" => "Marketingcampagne voor Nieuwe Productlijn", - "zaak" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "type" => "Campagne", - "status" => "gesloten", - "onderwerp" => "Ontwikkeling en lancering van een marketingcampagne voor een nieuwe productlijn.", - "toelichting" => "Deze taak omvat het plannen en uitvoeren van een marketingcampagne voor de lancering van een nieuwe productlijn. Het omvat het bepalen van de doelgroep, het ontwikkelen van marketingmateriaal, het inzetten van verschillende marketingkanalen en het monitoren van de resultaten.", - "actie" => "Bepalen van doelgroep, ontwikkelen van marketingmateriaal, uitvoeren van campagne, analyseren van resultaten." - ] - ]; - public function __construct( $appName, IRequest $request, @@ -129,10 +86,18 @@ public function create(CallService $callService): JSONResponse { // get post from requests $body = $this->request->getParams(); + $body['id'] = $this->get_guid(); //@todo remove this hotfic (or actually horror fix) + $body['data'] = []; $results = $callService->create(source: 'klanten', endpoint: 'taken', data: $body); return new JSONResponse($results); } + function get_guid() { + $data = PHP_MAJOR_VERSION < 7 ? openssl_random_pseudo_bytes(16) : random_bytes(16); + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // Set version to 0100 + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // Set bits 6-7 to 10 + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); + } /** * Update an object * diff --git a/lib/Controller/ZaakAuditTrailController.php b/lib/Controller/ZaakAuditTrailController.php index 6eef4ad..459686c 100644 --- a/lib/Controller/ZaakAuditTrailController.php +++ b/lib/Controller/ZaakAuditTrailController.php @@ -1,135 +1,135 @@ - [ - "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "name" => "Zaakt type 1", - "summary" => "summary for one" - ], - "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ - "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "name" => "Zaakt type 12", - "summary" => "summary for two" - ], - "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ - "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "name" => "Zaakt type 3", - "summary" => "summary for two" - ], - "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ - "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "name" => "Zaakt type 4", - "summary" => "summary for two" - ] - ]; - - public function __construct( - $appName, - IRequest $request, - private readonly IAppConfig $config - ) - { - parent::__construct($appName, $request); - } - - /** - * This returns the template of the main app's page - * It adds some data to the template (app version) - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function page(): TemplateResponse - { - return new TemplateResponse( - //Application::APP_ID, - 'zaakafhandelapp', - 'index', - [] - ); - } - - - /** - * Return (and serach) all objects - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function index(): JSONResponse - { - $results = ["results" => self::TEST_ARRAY]; - return new JSONResponse($results); - } - - /** - * Read a single object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function show(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - - /** - * Creatue an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function create(): JSONResponse - { - // get post from requests - return new JSONResponse([]); - } - - /** - * Update an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function update(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - /** - * Delate an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function destroy(string $id): JSONResponse - { - return new JSONResponse([]); - } -} + [ + "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", + "name" => "Zaakt type 1", + "summary" => "summary for one" + ], + "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ + "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", + "name" => "Zaakt type 12", + "summary" => "summary for two" + ], + "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ + "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", + "name" => "Zaakt type 3", + "summary" => "summary for two" + ], + "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ + "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", + "name" => "Zaakt type 4", + "summary" => "summary for two" + ] + ]; + + public function __construct( + $appName, + IRequest $request, + private readonly IAppConfig $config + ) + { + parent::__construct($appName, $request); + } + + /** + * This returns the template of the main app's page + * It adds some data to the template (app version) + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return TemplateResponse + */ + public function page(): TemplateResponse + { + return new TemplateResponse( + //Application::APP_ID, + 'zaakafhandelapp', + 'index', + [] + ); + } + + + /** + * Return (and serach) all objects + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function index(): JSONResponse + { + $results = ["results" => self::TEST_ARRAY]; + return new JSONResponse($results); + } + + /** + * Read a single object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function show(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + + /** + * Creatue an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function create(): JSONResponse + { + // get post from requests + return new JSONResponse([]); + } + + /** + * Update an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function update(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + /** + * Delate an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function destroy(string $id): JSONResponse + { + return new JSONResponse([]); + } +} diff --git a/lib/Controller/ZaakBesluitenController.php b/lib/Controller/ZaakBesluitenController.php index 1183fe3..d9da478 100644 --- a/lib/Controller/ZaakBesluitenController.php +++ b/lib/Controller/ZaakBesluitenController.php @@ -1,135 +1,135 @@ - [ - "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", - "name" => "Zaakt type 1", - "summary" => "summary for one" - ], - "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ - "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", - "name" => "Zaakt type 12", - "summary" => "summary for two" - ], - "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ - "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", - "name" => "Zaakt type 3", - "summary" => "summary for two" - ], - "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ - "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", - "name" => "Zaakt type 4", - "summary" => "summary for two" - ] - ]; - - public function __construct( - $appName, - IRequest $request, - private readonly IAppConfig $config - ) - { - parent::__construct($appName, $request); - } - - /** - * This returns the template of the main app's page - * It adds some data to the template (app version) - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return TemplateResponse - */ - public function page(): TemplateResponse - { - return new TemplateResponse( - //Application::APP_ID, - 'zaakafhandelapp', - 'index', - [] - ); - } - - - /** - * Return (and serach) all objects - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function index(): JSONResponse - { - $results = ["results" => self::TEST_ARRAY]; - return new JSONResponse($results); - } - - /** - * Read a single object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function show(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - - /** - * Creatue an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function create(): JSONResponse - { - // get post from requests - return new JSONResponse([]); - } - - /** - * Update an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function update(string $id): JSONResponse - { - $result = self::TEST_ARRAY[$id]; - return new JSONResponse($result); - } - - /** - * Delate an object - * - * @NoAdminRequired - * @NoCSRFRequired - * - * @return JSONResponse - */ - public function destroy(string $id): JSONResponse - { - return new JSONResponse([]); - } -} + [ + "id" => "5137a1e5-b54d-43ad-abd1-4b5bff5fcd3f", + "name" => "Zaakt type 1", + "summary" => "summary for one" + ], + "4c3edd34-a90d-4d2a-8894-adb5836ecde8" => [ + "id" => "4c3edd34-a90d-4d2a-8894-adb5836ecde8", + "name" => "Zaakt type 12", + "summary" => "summary for two" + ], + "15551d6f-44e3-43f3-a9d2-59e583c91eb0" => [ + "id" => "15551d6f-44e3-43f3-a9d2-59e583c91eb0", + "name" => "Zaakt type 3", + "summary" => "summary for two" + ], + "0a3a0ffb-dc03-4aae-b207-0ed1502e60da" => [ + "id" => "0a3a0ffb-dc03-4aae-b207-0ed1502e60da", + "name" => "Zaakt type 4", + "summary" => "summary for two" + ] + ]; + + public function __construct( + $appName, + IRequest $request, + private readonly IAppConfig $config + ) + { + parent::__construct($appName, $request); + } + + /** + * This returns the template of the main app's page + * It adds some data to the template (app version) + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return TemplateResponse + */ + public function page(): TemplateResponse + { + return new TemplateResponse( + //Application::APP_ID, + 'zaakafhandelapp', + 'index', + [] + ); + } + + + /** + * Return (and serach) all objects + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function index(): JSONResponse + { + $results = ["results" => self::TEST_ARRAY]; + return new JSONResponse($results); + } + + /** + * Read a single object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function show(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + + /** + * Creatue an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function create(): JSONResponse + { + // get post from requests + return new JSONResponse([]); + } + + /** + * Update an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function update(string $id): JSONResponse + { + $result = self::TEST_ARRAY[$id]; + return new JSONResponse($result); + } + + /** + * Delate an object + * + * @NoAdminRequired + * @NoCSRFRequired + * + * @return JSONResponse + */ + public function destroy(string $id): JSONResponse + { + return new JSONResponse([]); + } +} diff --git a/lib/Sections/ZaakAfhandelAppAdmin.php b/lib/Sections/ZaakAfhandelAppAdmin.php new file mode 100644 index 0000000..2f90ea6 --- /dev/null +++ b/lib/Sections/ZaakAfhandelAppAdmin.php @@ -0,0 +1,32 @@ +l = $l; + $this->urlGenerator = $urlGenerator; + } + + public function getIcon(): string { + return $this->urlGenerator->imagePath('core', 'actions/settings-dark.svg'); + } + + public function getID(): string { + return 'zaakafhandelapp'; + } + + public function getName(): string { + return $this->l->t('Zaak Afhandelapp'); + } + + public function getPriority(): int { + return 97; + } +} \ No newline at end of file diff --git a/lib/Service/ObjectService.php b/lib/Service/ObjectService.php new file mode 100644 index 0000000..925212a --- /dev/null +++ b/lib/Service/ObjectService.php @@ -0,0 +1,456 @@ +appName = 'opencatalogi'; + } + + /** + * Gets the appropriate mapper based on the object type. + * + * @param string $objectType The type of object to retrieve the mapper for. + * + * @return mixed The appropriate mapper. + * @throws InvalidArgumentException If an unknown object type is provided. + * @throws NotFoundExceptionInterface|ContainerExceptionInterface If OpenRegister service is not available or if register/schema is not configured. + * @throws Exception + */ + private function getMapper(string $objectType): mixed + { + $objectTypeLower = strtolower($objectType); + + // Get the source for the object type from the configuration + $source = $this->config->getValueString($this->appName, $objectTypeLower . '_source', 'internal'); + + // If the source is 'open_registers', use the OpenRegister service + if ($source === 'openregister') { + $openRegister = $this->getOpenRegisters(); + if ($openRegister === null) { + throw new Exception("OpenRegister service not available"); + } + $register = $this->config->getValueString($this->appName, $objectTypeLower . '_register', ''); + if (empty($register)) { + throw new Exception("Register not configured for $objectType"); + } + $schema = $this->config->getValueString($this->appName, $objectTypeLower . '_schema', ''); + if (empty($schema)) { + throw new Exception("Schema not configured for $objectType"); + } + return $openRegister->getMapper(register: $register, schema: $schema); + } + + // If the source is internal, return the appropriate mapper based on the object type + return match ($objectType) { + default => throw new InvalidArgumentException("Unknown object type: $objectType"), + }; + } + + /** + * Gets an object based on the object type and id. + * + * @param string $objectType The type of object to retrieve. + * @param string $id The id of the object to retrieve. + * + * @return mixed The retrieved object. + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface + */ + public function getObject(string $objectType, string $id, array $extend = []): mixed + { + // Clean up the id if it's a URI by getting only the last path part + if (filter_var($id, FILTER_VALIDATE_URL)) { + $parts = explode('/', rtrim($id, '/')); + $id = end($parts); + } + + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + // Use the mapper to find and return the object + $object = $mapper->find($id); + + // Convert the object to an array if it is not already an array + if (is_object($object) && method_exists($object, 'jsonSerialize')) { + $object = $object->jsonSerialize(); + } elseif (is_array($object) === false) { + $object = (array)$object; + } + + $object = $this->extendEntity(entity: $object, extend: $extend); + + return $object; + } + + /** + * Gets objects based on the object type, filters, search conditions, and other parameters. + * + * @param string $objectType The type of objects to retrieve. + * @param int|null $limit The maximum number of objects to retrieve. + * @param int|null $offset The offset from which to start retrieving objects. + * @param array|null $filters Filters to apply to the query. + * @param array|null $searchConditions Search conditions to apply to the query. + * @param array|null $searchParams Search parameters for the query. + * @param array|null $sort Sorting parameters for the query. + * @param array|null $extend Additional parameters for extending the query. + * + * @return array The retrieved objects as arrays. + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface + */ + public function getObjects( + string $objectType, + ?int $limit = null, + ?int $offset = null, + ?array $filters = [], + ?array $searchConditions = [], + ?array $searchParams = [], + ?array $sort = [], + ?array $extend = [] + ): array + { + + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + // Use the mapper to find and return the objects based on the provided parameters + $objects = $mapper->findAll($limit, $offset, $filters, sort: $sort); + + // Convert entity objects to arrays using jsonSerialize + $objects = array_map(function($object) { + return $object->jsonSerialize(); + }, $objects); + + // Extend the objects if the extend array is not empty + if (empty($extend) === false) { + $objects = array_map(function($object) use ($extend) { + return $this->extendEntity($object, $extend); + }, $objects); + } + + return $objects; + } + + /** + * Gets objects based on the object type, filters, search conditions, and other parameters. + * + * @param string $objectType The type of objects to retrieve. + * @param int|null $limit The maximum number of objects to retrieve. + * @param int|null $offset The offset from which to start retrieving objects. + * @param array|null $filters Filters to apply to the query. + * @param array|null $searchConditions Search conditions to apply to the query. + * @param array|null $searchParams Search parameters for the query. + * @param array|null $sort Sorting parameters for the query. + * @param array|null $extend Additional parameters for extending the query. + * + * @return array The retrieved objects as arrays. + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface + */ + public function getFacets( + string $objectType, + array $filters = [], + ): array + { + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + + // Use the mapper to find and return the objects based on the provided parameters + if ($mapper instanceof \OCA\OpenRegister\Service\ObjectService === true) { + return $mapper->getAggregations($filters); + } + + return []; + } + + /** + * Gets multiple objects based on the object type and ids. + * + * @param string $objectType The type of objects to retrieve. + * @param array $ids The ids of the objects to retrieve. + * + * @return array The retrieved objects. + * @throws ContainerExceptionInterface|NotFoundExceptionInterface If an unknown object type is provided. + */ + public function getMultipleObjects(string $objectType, array $ids): array + { + // Process the ids + $processedIds = array_map(function($id) { + if (is_object($id) && method_exists($id, 'getId')) { + return $id->getId(); + } elseif (is_array($id) && isset($id['id'])) { + return $id['id']; + } else { + return $id; + } + }, $ids); + + // Clean up the ids if they are URIs + $cleanedIds = array_map(function($id) { + // If the id is a URI, get only the last part of the path + if (filter_var($id, FILTER_VALIDATE_URL)) { + $parts = explode('/', rtrim($id, '/')); + return end($parts); + } + return $id; + }, $processedIds); + + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + + // Use the mapper to find and return multiple objects based on the provided cleaned ids + return $mapper->findMultiple($cleanedIds); + } + + /** + * Gets all objects of a specific type. + * + * @param string $objectType The type of objects to retrieve. + * @param int|null $limit The maximum number of objects to retrieve. + * @param int|null $offset The offset from which to start retrieving objects. + * + * @return array The retrieved objects. + * @throws ContainerExceptionInterface|NotFoundExceptionInterface If an unknown object type is provided. + */ + public function getAllObjects(string $objectType, ?int $limit = null, ?int $offset = null): array + { + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + + // Use the mapper to find and return all objects of the specified type + return $mapper->findAll($limit, $offset); + } + + /** + * Creates a new object or updates an existing one from an array of data. + * + * @param string $objectType The type of object to create or update. + * @param array $object The data to create or update the object from. + * @param bool $updateVersion If we should update the version or not, default = true. + * + * @return mixed The created or updated object. + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface + */ + public function saveObject(string $objectType, array $object, bool $updateVersion = true): mixed + { + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + // If the object has an id, update it; otherwise, create a new object + if (isset($object['id']) === true) { + return $mapper->updateFromArray($object['id'], $object, $updateVersion); + } + else { + return $mapper->createFromArray($object); + } + } + + /** + * Deletes an object based on the object type and id. + * + * @param string $objectType The type of object to delete. + * @param string|int $id The id of the object to delete. + * + * @return bool True if the object was successfully deleted, false otherwise. + * @throws ContainerExceptionInterface|NotFoundExceptionInterface|\OCP\DB\Exception If an unknown object type is provided. + */ + public function deleteObject(string $objectType, string|int $id): bool + { + // Get the appropriate mapper for the object type + $mapper = $this->getMapper($objectType); + + // Use the mapper to get and delete the object + try { + $object = $mapper->find($id); + $mapper->delete($object); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * Attempts to retrieve the OpenRegister service from the container. + * + * @return mixed|null The OpenRegister service if available, null otherwise. + * @throws ContainerExceptionInterface|NotFoundExceptionInterface + */ + public function getOpenRegisters(): ?\OCA\OpenRegister\Service\ObjectService + { + if (in_array(needle: 'openregister', haystack: $this->appManager->getInstalledApps()) === true) { + try { + // Attempt to get the OpenRegister service from the container + return $this->container->get('OCA\OpenRegister\Service\ObjectService'); + } catch (Exception $e) { + // If the service is not available, return null + return null; + } + } + + return null; + } + + private function getCount(string $objectType, array $filters = []): int + { + $mapper = $this->getMapper($objectType); + if($mapper instanceof \OCA\OpenRegister\Service\ObjectService === true) { + return $mapper->count(filters: $filters); + } + + return 0; + } + + /** + * Get a result array for a request based on the request and the object type. + * + * @param string $objectType The type of object to retrieve + * @param array $requestParams The request parameters + * + * @return array The result array containing objects and total count + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface + */ + public function getResultArrayForRequest(string $objectType, array $requestParams): array + { + // Extract specific parameters + $limit = $requestParams['limit'] ?? $requestParams['_limit'] ?? null; + $offset = $requestParams['offset'] ?? $requestParams['_offset'] ?? null; + $order = $requestParams['order'] ?? $requestParams['_order'] ?? []; + $extend = $requestParams['extend'] ?? $requestParams['_extend'] ?? null; + $page = $requestParams['page'] ?? $requestParams['_page'] ?? null; + + if ($page !== null && isset($limit)) { + $offset = $limit * ($page - 1); + } + + + // Ensure order and extend are arrays + if (is_string($order)) { + $order = array_map('trim', explode(',', $order)); + } + if (is_string($extend)) { + $extend = array_map('trim', explode(',', $extend)); + } + + // Remove unnecessary parameters from filters + $filters = $requestParams; + unset($filters['_route']); // TODO: Investigate why this is here and if it's needed + unset($filters['_extend'], $filters['_limit'], $filters['_offset'], $filters['_order'], $filters['_page']); + unset($filters['extend'], $filters['limit'], $filters['offset'], $filters['order'], $filters['page']); + + // Fetch objects based on filters and order + $objects = $this->getObjects( + objectType: $objectType, + limit: $limit, + offset: $offset, + filters: $filters, + sort: $order, + extend: $extend + ); + $facets = $this->getFacets($objectType, $filters); + + // Prepare response data + return [ + 'results' => $objects, + 'facets' => $facets, + 'total' => $this->getCount(objectType: $objectType, filters: $filters), + ]; + } + + /** + * Extends an entity with related objects based on the extend array. + * + * @param mixed $entity The entity to extend + * @param array $extend An array of properties to extend + * + * @return array The extended entity as an array + * @throws ContainerExceptionInterface|DoesNotExistException|MultipleObjectsReturnedException|NotFoundExceptionInterface If a property is not present on the entity + */ + public function extendEntity(mixed $entity, array $extend): array + { + $surpressMapperError = false; + // Convert the entity to an array if it's not already one + $result = is_array($entity) ? $entity : $entity->jsonSerialize(); + + if (in_array(needle: 'all', haystack: $extend) === true) { + $extend = array_keys($entity); + $surpressMapperError = true; + } + + // Iterate through each property to be extended + foreach ($extend as $property) { + // Create a singular property name + $singularProperty = rtrim($property, 's'); + + // Check if property or singular property are keys in the array + if (array_key_exists($property, $result)) { + $value = $result[$property]; + if (empty($value)) { + continue; + } + } elseif (array_key_exists($singularProperty, $result)) { + $value = $result[$singularProperty]; + } else { + throw new Exception("Property '$property' or '$singularProperty' is not present in the entity."); + } + + // Get a mapper for the property + $propertyObject = $property; + try { + $mapper = $this->getMapper($property); + $propertyObject = $singularProperty; + } catch (Exception $e) { + try { + $mapper = $this->getMapper($singularProperty); + $propertyObject = $singularProperty; + } catch (Exception $e) { + // If still no mapper, throw a no mapper available error + if ($surpressMapperError === true) { + continue; + } + throw new Exception("No mapper available for property '$property'."); + } + } + + // Update the values + if (is_array($value)) { + // If the value is an array, get multiple related objects + $result[$property] = $this->getMultipleObjects($propertyObject, $value); + } else { + // If the value is not an array, get a single related object + $objectId = is_object($value) ? $value->getId() : $value; + $result[$property] = $this->getObject($propertyObject, $objectId); + } + } + + // Return the extended entity as an array + return $result; + } +} diff --git a/lib/Settings/ZaakAfhandelAppAdmin.php b/lib/Settings/ZaakAfhandelAppAdmin.php new file mode 100644 index 0000000..15a7772 --- /dev/null +++ b/lib/Settings/ZaakAfhandelAppAdmin.php @@ -0,0 +1,43 @@ +config = $config; + $this->l = $l; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + $parameters = [ + 'mySetting' => $this->config->getSystemValue('zaakafhandelapp_setting', true), + ]; + + return new TemplateResponse('zaakafhandelapp', 'settings/admin', $parameters, 'admin'); + } + + public function getSection() { + return 'zaakafhandelapp'; // Name of the previously created section. + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + * + * E.g.: 70 + */ + public function getPriority() { + return 10; + } +} \ No newline at end of file diff --git a/openapi.json b/openapi.json index 1959154..abb523e 100644 --- a/openapi.json +++ b/openapi.json @@ -1,121 +1,121 @@ -{ - "openapi": "3.0.3", - "info": { - "title": "zaakafhandelapp", - "version": "0.0.1", - "description": "Zaak Afhandel App", - "license": { - "name": "agpl" - } - }, - "components": { - "securitySchemes": { - "basic_auth": { - "type": "http", - "scheme": "basic" - }, - "bearer_auth": { - "type": "http", - "scheme": "bearer" - } - }, - "schemas": { - "OCSMeta": { - "type": "object", - "required": [ - "status", - "statuscode" - ], - "properties": { - "status": { - "type": "string" - }, - "statuscode": { - "type": "integer" - }, - "message": { - "type": "string" - }, - "totalitems": { - "type": "string" - }, - "itemsperpage": { - "type": "string" - } - } - } - } - }, - "paths": { - "/ocs/v2.php/apps/zaakafhandelapp/api": { - "get": { - "operationId": "api-index", - "summary": "An example API endpoint", - "tags": [ - "api" - ], - "security": [ - { - "bearer_auth": [] - }, - { - "basic_auth": [] - } - ], - "parameters": [ - { - "name": "OCS-APIRequest", - "in": "header", - "description": "Required to be true for the API request to pass", - "required": true, - "schema": { - "type": "boolean", - "default": true - } - } - ], - "responses": { - "200": { - "description": "Data returned", - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "ocs" - ], - "properties": { - "ocs": { - "type": "object", - "required": [ - "meta", - "data" - ], - "properties": { - "meta": { - "$ref": "#/components/schemas/OCSMeta" - }, - "data": { - "type": "object", - "required": [ - "message" - ], - "properties": { - "message": { - "type": "string" - } - } - } - } - } - } - } - } - } - } - } - } - } - }, - "tags": [] +{ + "openapi": "3.0.3", + "info": { + "title": "zaakafhandelapp", + "version": "0.0.1", + "description": "Zaak Afhandel App", + "license": { + "name": "agpl" + } + }, + "components": { + "securitySchemes": { + "basic_auth": { + "type": "http", + "scheme": "basic" + }, + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + }, + "schemas": { + "OCSMeta": { + "type": "object", + "required": [ + "status", + "statuscode" + ], + "properties": { + "status": { + "type": "string" + }, + "statuscode": { + "type": "integer" + }, + "message": { + "type": "string" + }, + "totalitems": { + "type": "string" + }, + "itemsperpage": { + "type": "string" + } + } + } + } + }, + "paths": { + "/ocs/v2.php/apps/zaakafhandelapp/api": { + "get": { + "operationId": "api-index", + "summary": "An example API endpoint", + "tags": [ + "api" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Data returned", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "message" + ], + "properties": { + "message": { + "type": "string" + } + } + } + } + } + } + } + } + } + } + } + } + } + }, + "tags": [] } \ No newline at end of file diff --git a/psalm.xml b/psalm.xml index 567b000..1c901ed 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,20 +1,20 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/settings/adminSettings.php b/settings/adminSettings.php index 8ba3d17..d91cfae 100644 --- a/settings/adminSettings.php +++ b/settings/adminSettings.php @@ -1,98 +1,98 @@ -collector = $collector; - $this->config = $config; - $this->l = $l; - $this->dateTimeFormatter = $dateTimeFormatter; - $this->jobList = $jobList; - } - - /** - * @return TemplateResponse - */ - public function getForm() { - - // Getting the config - $zakenLocation = $this->config->getAppValue(Application::APP_ID, 'zaken_location', null); - $zakenKey = $this->config->getAppValue(Application::APP_ID, 'zaken_key', false); - $takenLocation = $this->config->getAppValue(Application::APP_ID, 'taken_location', null); - $takenKey = $this->config->getAppValue(Application::APP_ID, 'taken_key', null); - $contactMomentenLocation = $this->config->getAppValue(Application::APP_ID, 'contact_momenten_location', null); - $klantenLocation = $this->config->getAppValue(Application::APP_ID, 'klanten_location', null); - $klantenKey = $this->config->getAppValue(Application::APP_ID, 'klanten_key', null); - $zaakTypenLocation = $this->config->getAppValue(Application::APP_ID, 'zaak_typen_location', null); - $zaakTypenKey = $this->config->getAppValue(Application::APP_ID, 'zaak_typen_key', null); - - $parameters = [ - 'zakenLocation' => $zakenLocation, - 'zakenKey' => $zakenKey, - 'takenLocation' => $takenLocation, - 'takenKey' => $takenKey, - 'contactMomentenLocation' => $contactMomentenLocation, - 'klantenLocation' => $klantenLocation, - 'klantenKey' => $klantenKey, - 'zaakTypenLocation' => $zaakTypenLocation, - 'zaakTypenKey' => $zaakTypenKey, - ]; - - return new TemplateResponse(Application::APP_ID, 'adminForm', $parameters); - } - - /** - * @return string the section ID, e.g. 'sharing' - */ - public function getSection() { - return 'additional'; - } - - /** - * @return int whether the form should be rather on the top or bottom of - * the admin section. The forms are arranged in ascending order of the - * priority values. It is required to return a value between 0 and 100. - */ - public function getPriority() { - return 50; - } - -} +collector = $collector; + $this->config = $config; + $this->l = $l; + $this->dateTimeFormatter = $dateTimeFormatter; + $this->jobList = $jobList; + } + + /** + * @return TemplateResponse + */ + public function getForm() { + + // Getting the config + $zakenLocation = $this->config->getAppValue(Application::APP_ID, 'zaken_location', null); + $zakenKey = $this->config->getAppValue(Application::APP_ID, 'zaken_key', false); + $takenLocation = $this->config->getAppValue(Application::APP_ID, 'taken_location', null); + $takenKey = $this->config->getAppValue(Application::APP_ID, 'taken_key', null); + $contactMomentenLocation = $this->config->getAppValue(Application::APP_ID, 'contact_momenten_location', null); + $klantenLocation = $this->config->getAppValue(Application::APP_ID, 'klanten_location', null); + $klantenKey = $this->config->getAppValue(Application::APP_ID, 'klanten_key', null); + $zaakTypenLocation = $this->config->getAppValue(Application::APP_ID, 'zaak_typen_location', null); + $zaakTypenKey = $this->config->getAppValue(Application::APP_ID, 'zaak_typen_key', null); + + $parameters = [ + 'zakenLocation' => $zakenLocation, + 'zakenKey' => $zakenKey, + 'takenLocation' => $takenLocation, + 'takenKey' => $takenKey, + 'contactMomentenLocation' => $contactMomentenLocation, + 'klantenLocation' => $klantenLocation, + 'klantenKey' => $klantenKey, + 'zaakTypenLocation' => $zaakTypenLocation, + 'zaakTypenKey' => $zaakTypenKey, + ]; + + return new TemplateResponse(Application::APP_ID, 'adminForm', $parameters); + } + + /** + * @return string the section ID, e.g. 'sharing' + */ + public function getSection() { + return 'additional'; + } + + /** + * @return int whether the form should be rather on the top or bottom of + * the admin section. The forms are arranged in ascending order of the + * priority values. It is required to return a value between 0 and 100. + */ + public function getPriority() { + return 50; + } + +} diff --git a/src/App.vue b/src/App.vue index 2a1574b..2a2f5b2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,25 +1,31 @@ - - - + + + diff --git a/src/dialogs/Dialogs.vue b/src/dialogs/Dialogs.vue new file mode 100644 index 0000000..9650d92 --- /dev/null +++ b/src/dialogs/Dialogs.vue @@ -0,0 +1,15 @@ + + + diff --git a/src/mainScript.js b/src/main.js similarity index 87% rename from src/mainScript.js rename to src/main.js index 11977c1..bcc76d1 100644 --- a/src/mainScript.js +++ b/src/main.js @@ -1,14 +1,14 @@ -import Vue from 'vue' -import { PiniaVuePlugin } from 'pinia' -import pinia from './pinia.js' -import App from './App.vue' -Vue.mixin({ methods: { t, n } }) - -Vue.use(PiniaVuePlugin) - -new Vue( - { - pinia, - render: h => h(App), - }, -).$mount('#content') +import Vue from 'vue' +import { PiniaVuePlugin } from 'pinia' +import pinia from './pinia.js' +import App from './App.vue' +Vue.mixin({ methods: { t, n } }) + +Vue.use(PiniaVuePlugin) + +new Vue( + { + pinia, + render: h => h(App), + }, +).$mount('#content') \ No newline at end of file diff --git a/src/modals/Modals.vue b/src/modals/Modals.vue index 48a9401..7998ef4 100644 --- a/src/modals/Modals.vue +++ b/src/modals/Modals.vue @@ -6,6 +6,9 @@ import { navigationStore } from '../store/store.js'
+ + + @@ -19,6 +22,8 @@ import { navigationStore } from '../store/store.js' + + + + + + diff --git a/src/modals/zaakTypen/EditZaakType.vue b/src/modals/zaakTypen/EditZaakType.vue new file mode 100644 index 0000000..936dd84 --- /dev/null +++ b/src/modals/zaakTypen/EditZaakType.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/src/modals/zaken/AddZaak.vue b/src/modals/zaken/AddZaak.vue new file mode 100644 index 0000000..14ef252 --- /dev/null +++ b/src/modals/zaken/AddZaak.vue @@ -0,0 +1,184 @@ + + + + + + + diff --git a/src/navigation/Configuration.vue b/src/navigation/Configuration.vue index a34970c..a82837d 100644 --- a/src/navigation/Configuration.vue +++ b/src/navigation/Configuration.vue @@ -37,6 +37,10 @@
+ + {{ t('forms', 'Enable sharing') }} + + Mongo DB - - + + + + @@ -81,7 +89,7 @@ import { NcAppNavigation, NcAppNavigationList, NcAppNavigationItem, - NcAppNavigationNewItem, + NcAppNavigationNew, NcAppNavigationSettings, } from '@nextcloud/vue' @@ -97,6 +105,7 @@ import CalendarMonthOutline from 'vue-material-design-icons/CalendarMonthOutline import BriefcaseAccountOutline from 'vue-material-design-icons/BriefcaseAccountOutline.vue' import Plus from 'vue-material-design-icons/Plus.vue' import SortVariantLock from 'vue-material-design-icons/SortVariantLock.vue' +import Magnify from 'vue-material-design-icons/Magnify.vue' export default { name: 'MainMenu', @@ -104,8 +113,10 @@ export default { NcAppNavigation, NcAppNavigationList, NcAppNavigationItem, - NcAppNavigationNewItem, + NcAppNavigationNew, NcAppNavigationSettings, + // Icons + Magnify, Finance, AlphaTBoxOutline, ChatOutline, diff --git a/src/settings.js b/src/settings.js new file mode 100644 index 0000000..138884e --- /dev/null +++ b/src/settings.js @@ -0,0 +1,10 @@ +import Vue from 'vue' +import Settings from './views/settings/Settings.vue' + +Vue.mixin({ methods: { t, n } }) + +new Vue( + { + render: h => h(Settings), + }, +).$mount('#settings') diff --git a/src/sidebars/SideBars.vue b/src/sidebars/SideBars.vue new file mode 100644 index 0000000..c55fea8 --- /dev/null +++ b/src/sidebars/SideBars.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/src/sidebars/dashboard/DashboardSideBar.vue b/src/sidebars/dashboard/DashboardSideBar.vue new file mode 100644 index 0000000..43a42d0 --- /dev/null +++ b/src/sidebars/dashboard/DashboardSideBar.vue @@ -0,0 +1,61 @@ + + + + diff --git a/src/sidebars/search/SearchSideBar.vue b/src/sidebars/search/SearchSideBar.vue new file mode 100644 index 0000000..e1197f6 --- /dev/null +++ b/src/sidebars/search/SearchSideBar.vue @@ -0,0 +1,60 @@ + + + + diff --git a/src/store.js b/src/store.js new file mode 100644 index 0000000..a5f78d3 --- /dev/null +++ b/src/store.js @@ -0,0 +1,2 @@ +// This file is to remove import build errors. +// This file is not to be used for anything else and needs to be deleted when all imports are to the right store. diff --git a/src/views/Views.vue b/src/views/Views.vue index 3c3be95..15c6df3 100644 --- a/src/views/Views.vue +++ b/src/views/Views.vue @@ -26,6 +26,7 @@ import { NcAppContent } from '@nextcloud/vue' import BerichtenIndex from './berichten/BerichtenIndex.vue' import BesluitenIndex from './besluiten/BesluitenIndex.vue' import DashboardIndex from './dashboard/DashboardIndex.vue' +import SearchIndex from './search/SearchIndex.vue' import DocumentenIndex from './documenten/DocumentenIndex.vue' import KlantenIndex from './klanten/KlantenIndex.vue' import ResultatenIndex from './resultaten/ResultatenIndex.vue' @@ -41,6 +42,7 @@ export default { BerichtenIndex, BesluitenIndex, DashboardIndex, + SearchIndex, DocumentenIndex, KlantenIndex, ResultatenIndex, diff --git a/src/views/berichten/BerichtDetails.vue b/src/views/berichten/BerichtDetails.vue index ccdbe06..615598e 100644 --- a/src/views/berichten/BerichtDetails.vue +++ b/src/views/berichten/BerichtDetails.vue @@ -4,103 +4,102 @@ import { navigationStore } from '../../store/store.js' diff --git a/src/views/berichten/BerichtenList.vue b/src/views/berichten/BerichtenList.vue index 3db50a3..e7ced35 100644 --- a/src/views/berichten/BerichtenList.vue +++ b/src/views/berichten/BerichtenList.vue @@ -16,7 +16,7 @@ import { navigationStore } from '../../store/store.js' - + @@ -30,15 +30,15 @@ import { navigationStore } from '../../store/store.js'
-
- + + @click="store.setBerichtItem(bericht)">