fix file
This commit is contained in:
parent
99d54ce600
commit
991562a456
50
.github/dependabot.yml
vendored
50
.github/dependabot.yml
vendored
@ -1,50 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/vendor-bin/cs-fixer"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/vendor-bin/openapi-extractor"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/vendor-bin/phpunit"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
- package-ecosystem: composer
|
|
||||||
directory: "/vendor-bin/psalm"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
||||||
- package-ecosystem: npm
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: weekly
|
|
||||||
day: saturday
|
|
||||||
time: "03:00"
|
|
||||||
timezone: Europe/Paris
|
|
||||||
open-pull-requests-limit: 10
|
|
@ -1,31 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Block unconventional commits
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, ready_for_review, reopened, synchronize]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: block-unconventional-commits-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
block-unconventional-commits:
|
|
||||||
name: Block unconventional commits
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- uses: webiny/action-conventional-commits@8bc41ff4e7d423d56fa4905f6ff79209a78776c7 # v1.3.0
|
|
||||||
with:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
33
.github/workflows/fixup.yml
vendored
33
.github/workflows/fixup.yml
vendored
@ -1,33 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Block fixup and squash commits
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [opened, ready_for_review, reopened, synchronize]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: fixup-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
commit-message-check:
|
|
||||||
if: github.event.pull_request.draft == false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
pull-requests: write
|
|
||||||
name: Block fixup and squash commits
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Run check
|
|
||||||
uses: skjnldsv/block-fixup-merge-action@42d26e1b536ce61e5cf467d65fb76caf4aa85acf # v1
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
95
.github/workflows/lint-eslint.yml
vendored
95
.github/workflows/lint-eslint.yml
vendored
@ -1,95 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
#
|
|
||||||
# Use lint-eslint together with lint-eslint-when-unrelated to make eslint a required check for GitHub actions
|
|
||||||
# https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
|
|
||||||
|
|
||||||
name: Lint eslint
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lint-eslint-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
changes:
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
src: ${{ steps.changes.outputs.src}}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
|
|
||||||
id: changes
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
filters: |
|
|
||||||
src:
|
|
||||||
- '.github/workflows/**'
|
|
||||||
- 'src/**'
|
|
||||||
- 'appinfo/info.xml'
|
|
||||||
- 'package.json'
|
|
||||||
- 'package-lock.json'
|
|
||||||
- 'tsconfig.json'
|
|
||||||
- '.eslintrc.*'
|
|
||||||
- '.eslintignore'
|
|
||||||
- '**.js'
|
|
||||||
- '**.ts'
|
|
||||||
- '**.vue'
|
|
||||||
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
needs: changes
|
|
||||||
if: needs.changes.outputs.src != 'false'
|
|
||||||
|
|
||||||
name: NPM lint
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
|
||||||
id: versions
|
|
||||||
with:
|
|
||||||
fallbackNode: '^20'
|
|
||||||
fallbackNpm: '^10'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
env:
|
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
|
||||||
PUPPETEER_SKIP_DOWNLOAD: true
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: npm run lint
|
|
||||||
|
|
||||||
summary:
|
|
||||||
permissions:
|
|
||||||
contents: none
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
needs: [changes, lint]
|
|
||||||
|
|
||||||
if: always()
|
|
||||||
|
|
||||||
# This is the summary, we just avoid to rename it so that branch protection rules still match
|
|
||||||
name: eslint
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Summary status
|
|
||||||
run: if ${{ needs.changes.outputs.src != 'false' && needs.lint.result != 'success' }}; then exit 1; fi
|
|
33
.github/workflows/lint-info-xml.yml
vendored
33
.github/workflows/lint-info-xml.yml
vendored
@ -1,33 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Lint info.xml
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lint-info-xml-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
xml-linters:
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
|
|
||||||
name: info.xml lint
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Download schema
|
|
||||||
run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd
|
|
||||||
|
|
||||||
- name: Lint info.xml
|
|
||||||
uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2
|
|
||||||
with:
|
|
||||||
xml-file: ./appinfo/info.xml
|
|
||||||
xml-schema-file: ./info.xsd
|
|
45
.github/workflows/lint-php-cs.yml
vendored
45
.github/workflows/lint-php-cs.yml
vendored
@ -1,45 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Lint php-cs
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lint-php-cs-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
name: php-cs
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Get php version
|
|
||||||
id: versions
|
|
||||||
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
|
|
||||||
|
|
||||||
- name: Set up php${{ steps.versions.outputs.php-available }}
|
|
||||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ steps.versions.outputs.php-available }}
|
|
||||||
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
|
||||||
coverage: none
|
|
||||||
ini-file: development
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: composer run cs:check || ( echo 'Please run `composer run cs:fix` to format your code' && exit 1 )
|
|
67
.github/workflows/lint-php.yml
vendored
67
.github/workflows/lint-php.yml
vendored
@ -1,67 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Lint php
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lint-php-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
matrix:
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
outputs:
|
|
||||||
php-versions: ${{ steps.versions.outputs.php-versions }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout app
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
- name: Get version matrix
|
|
||||||
id: versions
|
|
||||||
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.0.0
|
|
||||||
|
|
||||||
php-lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: matrix
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
php-versions: ${{fromJson(needs.matrix.outputs.php-versions)}}
|
|
||||||
|
|
||||||
name: php-lint
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Set up php ${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
|
||||||
coverage: none
|
|
||||||
ini-file: development
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: composer run lint
|
|
||||||
|
|
||||||
summary:
|
|
||||||
permissions:
|
|
||||||
contents: none
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
needs: php-lint
|
|
||||||
|
|
||||||
if: always()
|
|
||||||
|
|
||||||
name: php-lint-summary
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Summary status
|
|
||||||
run: if ${{ needs.php-lint.result != 'success' && needs.php-lint.result != 'skipped' }}; then exit 1; fi
|
|
48
.github/workflows/lint-stylelint.yml
vendored
48
.github/workflows/lint-stylelint.yml
vendored
@ -1,48 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Lint stylelint
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: lint-stylelint-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
name: stylelint
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
|
||||||
id: versions
|
|
||||||
with:
|
|
||||||
fallbackNode: '^20'
|
|
||||||
fallbackNpm: '^10'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
env:
|
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
|
||||||
run: npm ci
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: npm run stylelint
|
|
73
.github/workflows/npm-audit-fix.yml
vendored
73
.github/workflows/npm-audit-fix.yml
vendored
@ -1,73 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Npm audit fix and compile
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
# At 2:30 on Sundays
|
|
||||||
- cron: '30 2 * * 0'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
branches: ['main', 'master', 'stable29', 'stable28', 'stable27']
|
|
||||||
|
|
||||||
name: npm-audit-fix-${{ matrix.branches }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
with:
|
|
||||||
ref: ${{ matrix.branches }}
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
|
||||||
id: versions
|
|
||||||
with:
|
|
||||||
fallbackNode: '^20'
|
|
||||||
fallbackNpm: '^10'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.versions.outputs.nodeVersion }}
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Fix npm audit
|
|
||||||
run: |
|
|
||||||
npm audit fix
|
|
||||||
|
|
||||||
- name: Run npm ci and npm run build
|
|
||||||
if: always()
|
|
||||||
env:
|
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
npm run build --if-present
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
|
||||||
if: always()
|
|
||||||
uses: peter-evans/create-pull-request@a4f52f8033a6168103c2538976c07b467e8163bc # v6.0.1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
commit-message: "fix(deps): fix npm audit"
|
|
||||||
committer: GitHub <noreply@github.com>
|
|
||||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
|
||||||
signoff: true
|
|
||||||
branch: automated/noid/${{ matrix.branches }}-fix-npm-audit
|
|
||||||
title: "[${{ matrix.branches }}] Fix npm audit"
|
|
||||||
body: |
|
|
||||||
Auto-generated fix of npm audit
|
|
||||||
labels: |
|
|
||||||
dependencies
|
|
||||||
3. to review
|
|
85
.github/workflows/openapi.yml
vendored
85
.github/workflows/openapi.yml
vendored
@ -1,85 +0,0 @@
|
|||||||
name: OpenAPI
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: openapi-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
openapi:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
if: ${{ github.repository_owner != 'nextcloud-gmbh' }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Get php version
|
|
||||||
id: php_versions
|
|
||||||
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
|
|
||||||
|
|
||||||
- name: Set up php
|
|
||||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ steps.php_versions.outputs.php-available }}
|
|
||||||
extensions: xml
|
|
||||||
coverage: none
|
|
||||||
ini-file: development
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Check Typescript OpenApi types
|
|
||||||
id: check_typescript_openapi
|
|
||||||
uses: andstor/file-existence-action@076e0072799f4942c8bc574a82233e1e4d13e9d6 # v3.0.0
|
|
||||||
with:
|
|
||||||
files: "src/types/openapi/openapi*.ts"
|
|
||||||
|
|
||||||
- name: Read package.json node and npm engines version
|
|
||||||
if: steps.check_typescript_openapi.outputs.files_exists == 'true'
|
|
||||||
uses: skjnldsv/read-package-engines-version-actions@8205673bab74a63eb9b8093402fd9e0e018663a1 # v2.2
|
|
||||||
id: node_versions
|
|
||||||
# Continue if no package.json
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
fallbackNode: '^20'
|
|
||||||
fallbackNpm: '^10'
|
|
||||||
|
|
||||||
- name: Set up node ${{ steps.node_versions.outputs.nodeVersion }}
|
|
||||||
if: ${{ steps.node_versions.outputs.nodeVersion }}
|
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
|
||||||
with:
|
|
||||||
node-version: ${{ steps.node_versions.outputs.nodeVersion }}
|
|
||||||
|
|
||||||
- name: Set up npm ${{ steps.node_versions.outputs.npmVersion }}
|
|
||||||
if: ${{ steps.node_versions.outputs.nodeVersion }}
|
|
||||||
run: npm i -g npm@"${{ steps.node_versions.outputs.npmVersion }}"
|
|
||||||
|
|
||||||
- name: Install dependencies & build
|
|
||||||
if: ${{ steps.node_versions.outputs.nodeVersion }}
|
|
||||||
env:
|
|
||||||
CYPRESS_INSTALL_BINARY: 0
|
|
||||||
PUPPETEER_SKIP_DOWNLOAD: true
|
|
||||||
run: |
|
|
||||||
npm ci
|
|
||||||
|
|
||||||
- name: Set up dependencies
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Regenerate OpenAPI
|
|
||||||
run: composer run openapi
|
|
||||||
|
|
||||||
- name: Check openapi*.json and typescript changes
|
|
||||||
run: |
|
|
||||||
bash -c "[[ ! \"`git status --porcelain `\" ]] || (echo 'Please run \"composer run openapi\" and commit the openapi*.json files and (if applicable) src/types/openapi/openapi*.ts, see the section \"Show changes on failure\" for details' && exit 1)"
|
|
||||||
|
|
||||||
- name: Show changes on failure
|
|
||||||
if: failure()
|
|
||||||
run: |
|
|
||||||
git status
|
|
||||||
git --no-pager diff
|
|
||||||
exit 1 # make it red to grab attention
|
|
68
.github/workflows/psalm-matrix.yml
vendored
68
.github/workflows/psalm-matrix.yml
vendored
@ -1,68 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Static analysis
|
|
||||||
|
|
||||||
on: pull_request
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: psalm-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
matrix:
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
outputs:
|
|
||||||
ocp-matrix: ${{ steps.versions.outputs.ocp-matrix }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout app
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
- name: Get version matrix
|
|
||||||
id: versions
|
|
||||||
uses: icewind1991/nextcloud-version-matrix@58becf3b4bb6dc6cef677b15e2fd8e7d48c0908f # v1.3.1
|
|
||||||
|
|
||||||
static-analysis:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: matrix
|
|
||||||
strategy:
|
|
||||||
# do not stop on another job's failure
|
|
||||||
fail-fast: false
|
|
||||||
matrix: ${{ fromJson(needs.matrix.outputs.ocp-matrix) }}
|
|
||||||
|
|
||||||
name: static-psalm-analysis ${{ matrix.ocp-version }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
|
|
||||||
- name: Set up php${{ matrix.php-versions }}
|
|
||||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php-versions }}
|
|
||||||
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
|
||||||
coverage: none
|
|
||||||
ini-file: development
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer i
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer require --dev nextcloud/ocp:${{ matrix.ocp-version }} --ignore-platform-reqs --with-dependencies
|
|
||||||
|
|
||||||
- name: Run coding standards check
|
|
||||||
run: composer run psalm
|
|
||||||
|
|
||||||
summary:
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
needs: static-analysis
|
|
||||||
|
|
||||||
if: always()
|
|
||||||
|
|
||||||
name: static-psalm-analysis-summary
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Summary status
|
|
||||||
run: if ${{ needs.static-analysis.result != 'success' }}; then exit 1; fi
|
|
@ -1,49 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Auto approve nextcloud/ocp
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request_target:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
- stable*
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: update-nextcloud-ocp-approve-merge-${{ github.head_ref || github.run_id }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
auto-approve-merge:
|
|
||||||
if: github.actor == 'nextcloud-command'
|
|
||||||
runs-on: ubuntu-latest-low
|
|
||||||
permissions:
|
|
||||||
# for hmarr/auto-approve-action to approve PRs
|
|
||||||
pull-requests: write
|
|
||||||
# for alexwilson/enable-github-automerge-action to approve PRs
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: mdecoleman/pr-branch-name@bab4c71506bcd299fb350af63bb8e53f2940a599 # v2.0.0
|
|
||||||
id: branchname
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
# GitHub actions bot approve
|
|
||||||
- uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2
|
|
||||||
if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
# Enable GitHub auto merge
|
|
||||||
- name: Auto merge
|
|
||||||
uses: alexwilson/enable-github-automerge-action@56e3117d1ae1540309dc8f7a9f2825bc3c5f06ff # main
|
|
||||||
if: startsWith(steps.branchname.outputs.branch, 'automated/noid/') && endsWith(steps.branchname.outputs.branch, 'update-nextcloud-ocp')
|
|
||||||
with:
|
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -1,94 +0,0 @@
|
|||||||
# This workflow is provided via the organization template repository
|
|
||||||
#
|
|
||||||
# https://github.com/nextcloud/.github
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
|
|
||||||
|
|
||||||
name: Update nextcloud/ocp
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: '5 2 * * 0'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
update-nextcloud-ocp:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
branches: ['main']
|
|
||||||
target: ['stable29']
|
|
||||||
|
|
||||||
name: update-nextcloud-ocp-${{ matrix.branches }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
|
||||||
with:
|
|
||||||
ref: ${{ matrix.branches }}
|
|
||||||
submodules: true
|
|
||||||
|
|
||||||
- name: Set up php8.2
|
|
||||||
uses: shivammathur/setup-php@a4e22b60bbb9c1021113f2860347b0759f66fe5d # v2
|
|
||||||
with:
|
|
||||||
php-version: 8.2
|
|
||||||
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
|
|
||||||
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib, sqlite, pdo_sqlite
|
|
||||||
coverage: none
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Read codeowners
|
|
||||||
id: codeowners
|
|
||||||
run: |
|
|
||||||
grep '/appinfo/info.xml' .github/CODEOWNERS | cut -f 2- -d ' ' | xargs | awk '{ print "codeowners="$0 }' >> $GITHUB_OUTPUT
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Composer install
|
|
||||||
run: composer install
|
|
||||||
|
|
||||||
- name: Composer update nextcloud/ocp
|
|
||||||
id: update_branch
|
|
||||||
run: composer require --dev nextcloud/ocp:dev-${{ matrix.target }}
|
|
||||||
|
|
||||||
- name: Raise on issue on failure
|
|
||||||
uses: dacbd/create-issue-action@cdb57ab6ff8862aa09fee2be6ba77a59581921c2 # v2.0.0
|
|
||||||
if: ${{ failure() && steps.update_branch.conclusion == 'failure' }}
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
title: Failed to update nextcloud/ocp package}
|
|
||||||
body: Please check the output of the GitHub action and manually resolve the issues<br>${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}<br>${{ steps.codeowners.outputs.codeowners }}
|
|
||||||
|
|
||||||
- name: Reset checkout 3rdparty
|
|
||||||
run: |
|
|
||||||
git clean -f 3rdparty
|
|
||||||
git checkout 3rdparty
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Reset checkout vendor
|
|
||||||
run: |
|
|
||||||
git clean -f vendor
|
|
||||||
git checkout vendor
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Reset checkout vendor-bin
|
|
||||||
run: |
|
|
||||||
git clean -f vendor-bin
|
|
||||||
git checkout vendor-bin
|
|
||||||
continue-on-error: true
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
|
||||||
uses: peter-evans/create-pull-request@a4f52f8033a6168103c2538976c07b467e8163bc # v6.0.1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.COMMAND_BOT_PAT }}
|
|
||||||
commit-message: "chore(dev-deps): Bump nextcloud/ocp package"
|
|
||||||
committer: GitHub <noreply@github.com>
|
|
||||||
author: nextcloud-command <nextcloud-command@users.noreply.github.com>
|
|
||||||
signoff: true
|
|
||||||
branch: automated/noid/${{ matrix.branches }}-update-nextcloud-ocp
|
|
||||||
title: "[${{ matrix.branches }}] Update nextcloud/ocp dependency"
|
|
||||||
body: |
|
|
||||||
Auto-generated update of [nextcloud/ocp](https://github.com/nextcloud-deps/ocp/) dependency
|
|
||||||
labels: |
|
|
||||||
dependencies
|
|
||||||
3. to review
|
|
@ -14,4 +14,13 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<nextcloud min-version="29" max-version="29"/>
|
<nextcloud min-version="29" max-version="29"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<navigations>
|
||||||
|
<navigation>
|
||||||
|
<id>webtransfer</id>
|
||||||
|
<name>Web Transfer</name>
|
||||||
|
<route>webtransfer.page.index</route>
|
||||||
|
<icon>app.svg</icon>
|
||||||
|
<type>link</type>
|
||||||
|
</navigation>
|
||||||
|
</navigations>
|
||||||
</info>
|
</info>
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
return [
|
return [
|
||||||
'routes' => [
|
'routes' => [
|
||||||
['name' => 'page#main', 'url' => '/', 'verb' => 'GET'],
|
['name' => 'page#main', 'url' => '/', 'verb' => 'GET'],
|
||||||
['name' => 'page#zipDrop', 'url' => '/zipDrop', 'verb' => 'GET'],
|
['name' => 'page#post', 'url' => '/post', 'verb' => 'POST'],
|
||||||
['name' => 'page#getZipFile', 'url' => '/getZipFile', 'verb' => 'GET']
|
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
@ -33,97 +33,15 @@ class PageController extends Controller {
|
|||||||
|
|
||||||
#[NoCSRFRequired]
|
#[NoCSRFRequired]
|
||||||
#[NoAdminRequired]
|
#[NoAdminRequired]
|
||||||
#[OpenAPI(OpenAPI::SCOPE_IGNORE)]
|
#[FrontpageRoute(verb: 'POST', url: '/zipDeposit')]
|
||||||
#[FrontpageRoute(verb: 'GET', url: '/zipDrop')]
|
public function post($archiveUrl, $token) {
|
||||||
public function zipDrop() {
|
$request = $this->request;
|
||||||
// Récupérer le paramètre subUrl (compatible GET et POST)
|
$parameters = array('archiveUrl' => $archiveUrl, 'token' => $token);
|
||||||
$subUrl = $this->request->getParam('subUrl');
|
|
||||||
|
|
||||||
if (!$subUrl) {
|
|
||||||
return new \OCP\AppFramework\Http\DataResponse([
|
|
||||||
'error' => 'Le paramètre subUrl est manquant'
|
|
||||||
], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optionnel : Validation de l'URL
|
|
||||||
if (filter_var($subUrl, FILTER_VALIDATE_URL) === false) {
|
|
||||||
return new \OCP\AppFramework\Http\DataResponse([
|
|
||||||
'error' => 'subUrl n\'est pas une URL valide'
|
|
||||||
], 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
$parameters = array('archiveUrl' => $subUrl);
|
|
||||||
|
|
||||||
// Réponse de succès
|
|
||||||
return new TemplateResponse(
|
return new TemplateResponse(
|
||||||
Application::APP_ID,
|
Application::APP_ID,
|
||||||
'index',
|
'index',
|
||||||
$parameters
|
$parameters
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[NoCSRFRequired]
|
|
||||||
#[NoAdminRequired]
|
|
||||||
#[OpenAPI(OpenAPI::SCOPE_IGNORE)]
|
|
||||||
#[FrontpageRoute(verb: 'GET', url: '/getZipFile')]
|
|
||||||
public function getZipFile() {
|
|
||||||
// Récupérer les données envoyées dans la requête
|
|
||||||
$zipUrl = $this->request->getParam('subUrl');
|
|
||||||
|
|
||||||
// Initialiser les paramètres de réponse
|
|
||||||
$parameters = [
|
|
||||||
'status' => 'error', // Par défaut, la réponse indique une erreur
|
|
||||||
'message' => '',
|
|
||||||
'data' => null
|
|
||||||
];
|
|
||||||
|
|
||||||
// Valider l'URL
|
|
||||||
if (!$zipUrl || filter_var($zipUrl, FILTER_VALIDATE_URL) === false) {
|
|
||||||
$parameters['message'] = 'Invalid URL';
|
|
||||||
return new JsonResponse($parameters, 400); // 400 Bad Request
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Initialiser cURL
|
|
||||||
$ch = curl_init();
|
|
||||||
curl_setopt($ch, CURLOPT_URL, $zipUrl);
|
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // Timeout de 10 secondes
|
|
||||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Suivre les redirections
|
|
||||||
|
|
||||||
// Récupérer le contenu
|
|
||||||
$response = curl_exec($ch);
|
|
||||||
|
|
||||||
// Gérer les erreurs cURL
|
|
||||||
if (curl_errno($ch)) {
|
|
||||||
$parameters['message'] = 'cURL error: ' . curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
return new JsonResponse(['parameters' => $parameters, 'status' => 500]); // 500 Internal Server Error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vérifier le code HTTP
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
if ($httpCode !== 200) {
|
|
||||||
$parameters['message'] = "HTTP error: $httpCode";
|
|
||||||
return new JsonResponse(['parameters' => $parameters, 'status' => $httpCode]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encodage explicite en UTF-8 si nécessaire
|
|
||||||
if (!mb_detect_encoding($response, 'UTF-8', true)) {
|
|
||||||
$response = utf8_encode($response);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Si tout est OK, construire la réponse
|
|
||||||
$parameters['status'] = 'success';
|
|
||||||
$parameters['message'] = 'File retrieved successfully';
|
|
||||||
$parameters['data'] = $response; // Encodage Base64 pour éviter les problèmes d'encodage JSON
|
|
||||||
|
|
||||||
return new JsonResponse(['parameters' => $parameters, 'status' => 200]); // 200 OK
|
|
||||||
} catch (\Exception $e) {
|
|
||||||
$parameters['message'] = 'Exception: ' . $e->getMessage();
|
|
||||||
return new JsonResponse(['parameters' => $parameters, 'status' => 500]); // 500 Internal Server Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
154
package-lock.json
generated
154
package-lock.json
generated
@ -13,8 +13,6 @@
|
|||||||
"@nextcloud/files": "^3.10.0",
|
"@nextcloud/files": "^3.10.0",
|
||||||
"@nextcloud/initial-state": "^2.2.0",
|
"@nextcloud/initial-state": "^2.2.0",
|
||||||
"@nextcloud/vue": "^8.20.0",
|
"@nextcloud/vue": "^8.20.0",
|
||||||
"file-type": "^19.6.0",
|
|
||||||
"i18next": "^24.0.2",
|
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"vue": "^2.7.16",
|
"vue": "^2.7.16",
|
||||||
"vue-material-design-icons": "^5.3.1"
|
"vue-material-design-icons": "^5.3.1"
|
||||||
@ -1820,12 +1818,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/@sec-ant/readable-stream": {
|
|
||||||
"version": "0.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
|
|
||||||
"integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@shikijs/core": {
|
"node_modules/@shikijs/core": {
|
||||||
"version": "1.23.1",
|
"version": "1.23.1",
|
||||||
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.23.1.tgz",
|
"resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.23.1.tgz",
|
||||||
@ -1889,12 +1881,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@tokenizer/token": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/body-parser": {
|
"node_modules/@types/body-parser": {
|
||||||
"version": "1.19.5",
|
"version": "1.19.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||||
@ -6725,24 +6711,6 @@
|
|||||||
"node": "^10.12.0 || >=12.0.0"
|
"node": "^10.12.0 || >=12.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/file-type": {
|
|
||||||
"version": "19.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/file-type/-/file-type-19.6.0.tgz",
|
|
||||||
"integrity": "sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"get-stream": "^9.0.1",
|
|
||||||
"strtok3": "^9.0.1",
|
|
||||||
"token-types": "^6.0.0",
|
|
||||||
"uint8array-extras": "^1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
@ -7095,22 +7063,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/get-stream": {
|
|
||||||
"version": "9.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
|
|
||||||
"integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@sec-ant/readable-stream": "^0.4.1",
|
|
||||||
"is-stream": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/get-symbol-description": {
|
"node_modules/get-symbol-description": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
|
||||||
@ -7830,37 +7782,6 @@
|
|||||||
"node": ">=10.18"
|
"node": ">=10.18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i18next": {
|
|
||||||
"version": "24.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-24.0.2.tgz",
|
|
||||||
"integrity": "sha512-D88xyIGcWAKwBTAs4RSqASi8NXR/NhCVSTM4LDbdoU8qb/5dcEZjNCLDhtQBB7Epw/Cp1w2vH/3ujoTbqLSs5g==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://locize.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://locize.com/i18next.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.23.2"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"typescript": "^5"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"typescript": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ical.js": {
|
"node_modules/ical.js": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ical.js/-/ical.js-2.1.0.tgz",
|
||||||
@ -7899,6 +7820,7 @@
|
|||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||||
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@ -7913,7 +7835,8 @@
|
|||||||
"url": "https://feross.org/support"
|
"url": "https://feross.org/support"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "BSD-3-Clause"
|
"license": "BSD-3-Clause",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
@ -8600,18 +8523,6 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/is-stream": {
|
|
||||||
"version": "4.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-string": {
|
"node_modules/is-string": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||||
@ -11100,19 +11011,6 @@
|
|||||||
"node": ">=0.12"
|
"node": ">=0.12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/peek-readable": {
|
|
||||||
"version": "5.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.3.1.tgz",
|
|
||||||
"integrity": "sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/Borewit"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@ -13588,23 +13486,6 @@
|
|||||||
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
|
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/strtok3": {
|
|
||||||
"version": "9.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-9.1.1.tgz",
|
|
||||||
"integrity": "sha512-FhwotcEqjr241ZbjFzjlIYg6c5/L/s4yBGWSMvJ9UoExiSqL+FnFA/CaeZx17WGaZMS/4SOZp8wH18jSS4R4lw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@tokenizer/token": "^0.3.0",
|
|
||||||
"peek-readable": "^5.3.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/Borewit"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/style-loader": {
|
"node_modules/style-loader": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz",
|
||||||
@ -14332,23 +14213,6 @@
|
|||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/token-types": {
|
|
||||||
"version": "6.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz",
|
|
||||||
"integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@tokenizer/token": "^0.3.0",
|
|
||||||
"ieee754": "^1.2.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.16"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/Borewit"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tree-dump": {
|
"node_modules/tree-dump": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz",
|
||||||
@ -14691,18 +14555,6 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/uint8array-extras": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||||
|
@ -11,9 +11,7 @@
|
|||||||
"dev": "NODE_ENV=development webpack --config webpack.js --progress",
|
"dev": "NODE_ENV=development webpack --config webpack.js --progress",
|
||||||
"watch": "NODE_ENV=development webpack --config webpack.js --progress --watch",
|
"watch": "NODE_ENV=development webpack --config webpack.js --progress --watch",
|
||||||
"lint": "eslint src",
|
"lint": "eslint src",
|
||||||
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css",
|
"stylelint": "stylelint src/**/*.vue src/**/*.scss src/**/*.css"
|
||||||
"tailwind": "npx tailwindcss -i ./src/input.css -o ./src/output.css",
|
|
||||||
"buildAll": "npm i && npm run tailwind && npm run build"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"extends @nextcloud/browserslist-config"
|
"extends @nextcloud/browserslist-config"
|
||||||
@ -23,8 +21,6 @@
|
|||||||
"@nextcloud/files": "^3.10.0",
|
"@nextcloud/files": "^3.10.0",
|
||||||
"@nextcloud/initial-state": "^2.2.0",
|
"@nextcloud/initial-state": "^2.2.0",
|
||||||
"@nextcloud/vue": "^8.20.0",
|
"@nextcloud/vue": "^8.20.0",
|
||||||
"file-type": "^19.6.0",
|
|
||||||
"i18next": "^24.0.2",
|
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"vue": "^2.7.16",
|
"vue": "^2.7.16",
|
||||||
"vue-material-design-icons": "^5.3.1"
|
"vue-material-design-icons": "^5.3.1"
|
||||||
|
31
src/App.vue
31
src/App.vue
@ -1,16 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="app" class="h-full w-full dark:bg-black/80 bg-white/80">
|
<div id="app" class="h-full w-full bg-black/80">
|
||||||
<!-- Conteneur principal, ajustement en flex-row à partir de sm -->
|
<!-- Conteneur principal, ajustement en flex-row à partir de sm -->
|
||||||
<div class="h-full w-full flex flex-col sm:flex-row">
|
<div class="h-full w-full flex flex-col sm:flex-row">
|
||||||
<!-- Première section -->
|
<!-- Première section -->
|
||||||
<div
|
<div
|
||||||
class="w-full sm:w-1/3 max-sm:h-2/5 p-4 sm:m-6 sm:mr-0 rounded-xl dark:bg-NcBlack/40 bg-white/80">
|
class="w-full sm:w-1/3 max-sm:h-2/5 p-4 sm:m-6 sm:mr-0 rounded-xl bg-NcBlack/40">
|
||||||
<WebContentViewer :translate="translate" @file-upload="handleFileUpload" @dragEnded="toggleDragEnded" :zipUrl="zipUrl"/>
|
<WebContentViewer @zip-upload="handleZipUpload" @file-upload="handleFileUpload" @dragEnded="toggleDragEnded" zipUrl="http://localhost:8000/dummyZip.zip"/>
|
||||||
</div>
|
</div>
|
||||||
<!-- Deuxième section -->
|
<!-- Deuxième section -->
|
||||||
<div
|
<div
|
||||||
class="w-full sm:w-2/3 max-sm:h-3/5 p-4 sm:m-6 sm:ml-4 dark:bg-NcBlack bg-white rounded-xl">
|
class="w-full sm:w-2/3 max-sm:h-3/5 p-4 sm:m-6 sm:ml-4 bg-NcBlack rounded-xl">
|
||||||
<FileTable :file="sharedFile" :dragEnded="dragEnded" :translate="translate" @dragEnded="toggleDragEnded"/>
|
<FileTable :file="sharedFile" :zip="zip" :dragEnded="dragEnded" @dragEnded="toggleDragEnded"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -21,16 +21,6 @@ import FileTable from './components/FileTable.vue';
|
|||||||
import WebContentViewer from './components/WebContentViewer.vue';
|
import WebContentViewer from './components/WebContentViewer.vue';
|
||||||
import './output.css';
|
import './output.css';
|
||||||
|
|
||||||
// Traduction
|
|
||||||
import i18next from "i18next";
|
|
||||||
import file from "./assets/traduction.json";
|
|
||||||
|
|
||||||
await i18next.init({
|
|
||||||
lng: navigator.language.split('-')[0],
|
|
||||||
fallbackLng: "en",
|
|
||||||
resources: file,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
@ -38,11 +28,9 @@ export default {
|
|||||||
WebContentViewer
|
WebContentViewer
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
let zipUrl = document.getElementById('archiveInfos').getAttribute('dataarchiveurl');
|
|
||||||
//console.log(zipUrl)
|
|
||||||
return {
|
return {
|
||||||
zipUrl,
|
|
||||||
sharedFile: null,
|
sharedFile: null,
|
||||||
|
zip: null,
|
||||||
dragEnded: false,
|
dragEnded: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -50,13 +38,14 @@ export default {
|
|||||||
handleFileUpload(file) {
|
handleFileUpload(file) {
|
||||||
this.sharedFile = file;
|
this.sharedFile = file;
|
||||||
},
|
},
|
||||||
|
handleZipUpload(zip) {
|
||||||
|
this.zip = zip;
|
||||||
|
},
|
||||||
toggleDragEnded(){
|
toggleDragEnded(){
|
||||||
this.dragEnded = !this.dragEnded;
|
this.dragEnded = !this.dragEnded;
|
||||||
|
this.zip = null;
|
||||||
this.sharedFile = null;
|
this.sharedFile = null;
|
||||||
},
|
},
|
||||||
translate(id) {
|
|
||||||
return i18next.t(id)
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50" @click="closeModal">
|
<div class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50" @click="closeModal">
|
||||||
<div class="dark:bg-NcBlack bg-white rounded-lg shadow-lg p-6 w-96" @click.stop>
|
<div class="bg-NcBlack rounded-lg shadow-lg p-6 w-96" @click.stop>
|
||||||
<h2 class="text-lg font-semibold mb-4">{{ translate('modify.file.name') }}</h2>
|
<h2 class="text-lg font-semibold mb-4">Modifier le nom du fichier</h2>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="newFileName"
|
v-model="newFileName"
|
||||||
@ -11,8 +11,8 @@
|
|||||||
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end mt-4 space-x-2">
|
<div class="flex justify-end mt-4 space-x-2">
|
||||||
<button @click="save" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('rename') }}</button>
|
<button @click="save" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Sauvegarder</button>
|
||||||
<button @click="closeModal" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('cancel') }}</button>
|
<button @click="closeModal" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -29,19 +29,13 @@ export default {
|
|||||||
isDirectory:{
|
isDirectory:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
type: Function,
|
|
||||||
Required: true,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
let newFileName = this.initialFileName;
|
var newFileName = this.initialFileName;
|
||||||
let extension = '';
|
var extension = '';
|
||||||
let nbParts = 1;
|
|
||||||
if(!this.isDirectory) {
|
if(!this.isDirectory) {
|
||||||
let nameSplit = newFileName.split('.');
|
let nameSplit = newFileName.split('.');
|
||||||
nbParts = nameSplit.length;
|
|
||||||
if (nameSplit.length > 1) {
|
if (nameSplit.length > 1) {
|
||||||
extension = nameSplit.pop();
|
extension = nameSplit.pop();
|
||||||
}
|
}
|
||||||
@ -50,7 +44,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
newFileName,
|
newFileName,
|
||||||
extension,
|
extension,
|
||||||
nbParts
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -78,36 +71,17 @@ export default {
|
|||||||
},
|
},
|
||||||
onInputChange() {
|
onInputChange() {
|
||||||
if (!this.isDirectory) {
|
if (!this.isDirectory) {
|
||||||
this.newFileName = this.removeExtensionSurplus(this.newFileName);
|
const fileNameWithoutExtension = this.newFileName.slice(0, this.newFileName.lastIndexOf('.'));
|
||||||
let lastIndex = this.newFileName.lastIndexOf('.');
|
|
||||||
let fileNameWithoutExtension;
|
|
||||||
if(lastIndex != -1) {
|
|
||||||
fileNameWithoutExtension = this.newFileName.slice(0, lastIndex);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fileNameWithoutExtension = this.newFileName.slice(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const newFileNameWithOriginalExtension = fileNameWithoutExtension + '.' + this.extension;
|
const newFileNameWithOriginalExtension = fileNameWithoutExtension + '.' + this.extension;
|
||||||
|
|
||||||
// Si l'extension est différente de celle d'origine, on la rétablit
|
// Si l'extension est différente de celle d'origine, on la rétablit
|
||||||
if (this.extension !== '' && this.newFileName !== newFileNameWithOriginalExtension) {
|
if (this.extension !== '' && this.newFileName !== newFileNameWithOriginalExtension) {
|
||||||
// Vous pouvez ici vérifier si l'extension a été modifiée et la rétablir
|
// Vous pouvez ici vérifier si l'extension a été modifiée et la rétablir
|
||||||
|
|
||||||
this.newFileName = newFileNameWithOriginalExtension;
|
this.newFileName = newFileNameWithOriginalExtension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeExtensionSurplus(name){
|
|
||||||
let splitName = name.split('.');
|
|
||||||
|
|
||||||
if(this.nbParts != splitName.length) {
|
|
||||||
let lenExtension = this.extension.length;
|
|
||||||
return name.slice(0, name.length - lenExtension);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50">
|
<div class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50">
|
||||||
<div v-if="!displayRename && !displayOverwrite" class="dark:bg-NcBlack bg-white rounded-lg shadow-lg p-6 w-96">
|
<div v-if="!displayRename && !displayOverwrite" class="bg-NcBlack rounded-lg shadow-lg p-6 w-96">
|
||||||
<h2 class="text-lg font-semibold mb-4">{{ translate('file.already.exist') }}</h2>
|
<h2 class="text-lg font-semibold mb-4">Le fichier existe déjà</h2>
|
||||||
<p>{{ translate('file.pt.1') }}{{ fileName }}{{ translate('file.pt.2') }}</p>
|
<p>Le fichier "{{ fileName }}" existe déjà. Que voulez-vous faire ?</p>
|
||||||
<div class="flex justify-end mt-4 space-x-2">
|
<div class="flex justify-end mt-4 space-x-2">
|
||||||
<button @click="toggleOverwrite">{{ translate('overwrite') }}</button>
|
<button @click="toggleOverwrite">Écraser</button>
|
||||||
<button v-if="!isDirectory" @click="toggleRename">{{ translate('rename') }}</button>
|
<button v-if="!isDirectory" @click="toggleRename">Renommer</button>
|
||||||
<button @click="onCancel">{{ translate('cancel') }}</button>
|
<button @click="onCancel">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Renommer le fichier -->
|
<!-- Renommer le fichier -->
|
||||||
<div v-if="displayRename" class="dark:bg-NcBlack bg-white rounded-lg shadow-lg p-6 w-96">
|
<div v-if="displayRename" class="bg-NcBlack rounded-lg shadow-lg p-6 w-96">
|
||||||
<h2 class="text-lg font-semibold mb-4">{{ translate('change.file.name') }}</h2>
|
<h2 class="text-lg font-semibold mb-4">Modifier le nom du fichier</h2>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
v-model="newFileName"
|
v-model="newFileName"
|
||||||
@input="onInputChange"
|
@input="onInputChange"
|
||||||
@keyup.enter="save"
|
@keyup.enter="save"
|
||||||
:placeholder="translate('enter.file.name')"
|
placeholder="Entrez le nom du fichier"
|
||||||
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-end mt-4 space-x-2">
|
<div class="flex justify-end mt-4 space-x-2">
|
||||||
<button @click="save" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('confirm') }}</button>
|
<button @click="save" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Valider</button>
|
||||||
<button @click="toggleRename" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('cancel') }}</button>
|
<button @click="toggleRename" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Appliquer l'ecrasement a tous -->
|
<!-- Appliquer l'ecrasement a tous -->
|
||||||
<div v-if="displayOverwrite" class="dark:bg-NcBlack bg-white rounded-lg shadow-lg p-6 w-96">
|
<div v-if="displayOverwrite" class="bg-NcBlack rounded-lg shadow-lg p-6 w-96">
|
||||||
<h2 class="text-lg font-semibold mb-4">{{ translate('you.are.going.to.erase.file.folder') }}</h2>
|
<h2 class="text-lg font-semibold mb-4">Vous allez ecraser le fichier/dossier</h2>
|
||||||
<div class="flex items-center content-evenly">
|
<div class="flex items-center content-evenly">
|
||||||
<input type="checkbox" v-model="forAll" />
|
<input type="checkbox" v-model="forAll" />
|
||||||
<p>{{ translate('apply.to.all.*') }}</p>
|
<p>Appliquer à tous*</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-gray-400">{{ translate('*.text') }}</p>
|
<p class="text-xs text-gray-400">* ecrasera tous les fichiers qui ont le même nom sur votre dépôt</p>
|
||||||
<div class="flex justify-end mt-4 space-x-2">
|
<div class="flex justify-end mt-4 space-x-2">
|
||||||
<button @click="onOverwrite" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('confirm') }}</button>
|
<button @click="onOverwrite" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Valider</button>
|
||||||
<button @click="toggleOverwrite" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">{{ translate('cancel') }}</button>
|
<button @click="toggleOverwrite" class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">Annuler</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -53,10 +53,6 @@ export default {
|
|||||||
isDirectory:{
|
isDirectory:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
type: Function,
|
|
||||||
Required: true,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
@ -6,13 +6,13 @@
|
|||||||
:class="getClassButton('default')"
|
:class="getClassButton('default')"
|
||||||
@click="changeTab('default')"
|
@click="changeTab('default')"
|
||||||
>
|
>
|
||||||
{{ translate('all.files') }}
|
Tous les fichiers
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
:class="getClassButton('favorites')"
|
:class="getClassButton('favorites')"
|
||||||
@click="changeTab('favorites')"
|
@click="changeTab('favorites')"
|
||||||
>
|
>
|
||||||
{{ translate('favorites') }}
|
Favoris
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -27,10 +27,10 @@
|
|||||||
</NcBreadcrumb>
|
</NcBreadcrumb>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<div class="flex items-center ml-2">
|
<div class="flex items-center ml-2">
|
||||||
<button v-if="!isTransfering" @click="toggleAddFilePopup" :disabled="currentTab === 'favorites' && current_dir === '/'"
|
<button v-if="!isTransfering" @click="toggleAddFilePopup"
|
||||||
class="flex items-center space-x-2 bg-blue-100 text-blue-600 font-medium px-4 py-2 rounded-md hover:bg-blue-200 transition">
|
class="flex items-center space-x-2 bg-blue-100 text-blue-600 font-medium px-4 py-2 rounded-md hover:bg-blue-200 transition">
|
||||||
<Plus :size="20" />
|
<Plus :size="20" />
|
||||||
<span>{{translate('new')}}</span>
|
<span>Nouveau</span>
|
||||||
</button>
|
</button>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<ProgressBar :value="transferProgress" :color="transferStatus" />
|
<ProgressBar :value="transferProgress" :color="transferStatus" />
|
||||||
@ -44,18 +44,18 @@
|
|||||||
<!-- Popup pour la création de fichier -->
|
<!-- Popup pour la création de fichier -->
|
||||||
<div v-if="isAddFilePopupVisible"
|
<div v-if="isAddFilePopupVisible"
|
||||||
class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50">
|
class="fixed inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50 z-50">
|
||||||
<div class="dark:bg-NcBlack bg-white rounded-lg shadow-lg p-6 w-96">
|
<div class="bg-NcBlack rounded-lg shadow-lg p-6 w-96">
|
||||||
<h2 class="text-lg font-semibold mb-4">{{ translate('create.new.file') }}</h2>
|
<h2 class="text-lg font-semibold mb-4">Créer un nouveau fichier</h2>
|
||||||
<input v-model="newFileName" type="text" :placeholder="translate('name.of.file')"
|
<input v-model="newFileName" type="text" placeholder="Nom du fichier"
|
||||||
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
class="w-full px-4 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
<div class="flex justify-end mt-4 space-x-2">
|
<div class="flex justify-end mt-4 space-x-2">
|
||||||
<button @click="createNewFile"
|
|
||||||
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition">
|
|
||||||
{{translate('create')}}
|
|
||||||
</button>
|
|
||||||
<button @click="toggleAddFilePopup"
|
<button @click="toggleAddFilePopup"
|
||||||
class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">
|
class="px-4 py-2 bg-gray-200 text-gray-700 rounded-md hover:bg-gray-300 transition">
|
||||||
{{translate('cancel')}}
|
Annuler
|
||||||
|
</button>
|
||||||
|
<button @click="createNewFile"
|
||||||
|
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition">
|
||||||
|
Créer
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -63,10 +63,10 @@
|
|||||||
|
|
||||||
<!-- En-tête -->
|
<!-- En-tête -->
|
||||||
<div class="flex h-12 items-center border-b border-gray-300">
|
<div class="flex h-12 items-center border-b border-gray-300">
|
||||||
<div class="w-7/12 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">{{ translate('name') }}</div>
|
<div class="w-7/12 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">Nom</div>
|
||||||
<div class="w-2/12 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">{{ translate('type') }}</div>
|
<div class="w-2/12 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">Type</div>
|
||||||
<div class="w-2/12 px-4 py-2 text-gray-500 font-semibold">{{ translate('size') }}</div>
|
<div class="w-2/12 px-4 py-2 text-gray-500 font-semibold">Taille</div>
|
||||||
<div class="w-1/12 px-4 py-2 text-gray-500 font-semibold">{{ translate('options') }}</div>
|
<div class="w-1/12 px-4 py-2 text-gray-500 font-semibold">Options</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Contenu -->
|
<!-- Contenu -->
|
||||||
@ -78,12 +78,12 @@
|
|||||||
@dragleave.prevent="onDragLeave($event)" @dragend="onDragEnd">
|
@dragleave.prevent="onDragLeave($event)" @dragend="onDragEnd">
|
||||||
|
|
||||||
<div v-for="file in files" :key="file.filename"
|
<div v-for="file in files" :key="file.filename"
|
||||||
class="flex h-16 items-center dark:hover:bg-NcGray hover:bg-NcWhite rounded-lg border-b last:border-b-0 border-gray-300 cursor-pointer"
|
class="flex h-16 items-center hover:bg-NcGray rounded-lg border-b last:border-b-0 border-gray-300"
|
||||||
@click="handleClickElem(file)">
|
@click="handleClickElem(file)">
|
||||||
|
|
||||||
<!-- Nom -->
|
<!-- Nom -->
|
||||||
<div class="w-7/12 flex items-center px-4 py-2 border-r border-gray-300 cursor-pointer">
|
<div class="w-7/12 flex items-center px-4 py-2 border-r border-gray-300">
|
||||||
<div class="w-12 h-12 flex items-center justify-cente cursor-pointer">
|
<div class="w-12 h-12 flex items-center justify-center">
|
||||||
<template v-if="file.type === 'directory'">
|
<template v-if="file.type === 'directory'">
|
||||||
<svg fill="currentColor" viewBox="0 0 24 24" class="text-NcBlue w-10 h-10 ">
|
<svg fill="currentColor" viewBox="0 0 24 24" class="text-NcBlue w-10 h-10 ">
|
||||||
<path
|
<path
|
||||||
@ -92,7 +92,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="file.type === 'file' && file.basename.split('.').pop() !== 'zip'">
|
<template v-if="file.type === 'file' && file.basename.split('.').pop() !== 'zip'">
|
||||||
<div :class="['flex items-center justify-center cursor-pointer']">
|
<div :class="['flex items-center justify-center']">
|
||||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
||||||
class="w-10 h-10"
|
class="w-10 h-10"
|
||||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
||||||
@ -114,45 +114,46 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Type -->
|
<!-- Type -->
|
||||||
<div class="w-2/12 px-4 py-2 border-r border-gray-300 cursor-pointer">
|
<div class="w-2/12 px-4 py-2 border-r border-gray-300">
|
||||||
{{ file.type === 'directory' ? 'Dossier' : 'Fichier' }}
|
{{ file.type === 'directory' ? 'Dossier' : 'Fichier' }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Taille -->
|
<!-- Taille -->
|
||||||
<div class="w-2/12 px-4 py-2 cursor-pointer">
|
<div class="w-2/12 px-4 py-2">
|
||||||
{{ file.type === 'directory' ? '-' : formatFileSize(file.size) }}
|
{{ file.type === 'directory' ? '-' : formatFileSize(file.size) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Options -->
|
<!-- Options -->
|
||||||
<div class="w-1/12 px-4 py-2" @click.stop>
|
<div class="w-1/12 px-4 py-2" @click.stop>
|
||||||
<NcActions>
|
<NcActions>
|
||||||
<NcActionButton @click="deleteElem(file)" :closeAfterClick="true">
|
<NcActionButton @click="deleteElem(file)">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<Delete :size="20" />
|
<Delete :size="20" />
|
||||||
</template>
|
</template>
|
||||||
{{ translate('delete') }}
|
Supprimer
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
<NcActionButton @click="editElem(file)" :closeAfterClick="true">
|
<NcActionButton @click="editElem(file)">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<Pencil :size="20" />
|
<Pencil :size="20" />
|
||||||
</template>
|
</template>
|
||||||
{{ translate('edit') }}
|
Editer
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<EditFileName v-if="!editDialogDisabled" :initialFileName="initialFileName" :isDirectory="isDirectory" :translate="translate"
|
<EditFileName v-if="!editDialogDisabled" :initialFileName="initialFileName" :isDirectory="isDirectory"
|
||||||
@update="updateFileName" @close="closeEditDialog">
|
@update="updateFileName" @close="closeEditDialog">
|
||||||
</EditFileName>
|
</EditFileName>
|
||||||
<FileExistsDialog v-if="!fileExistDialogDisabled" :fileName="initialFileName" :isDirectory="isDirectory" :translate="translate"
|
<FileExistsDialog v-if="!fileExistDialogDisabled" :fileName="initialFileName" :isDirectory="isDirectory" @overwrite="setOverwrite" @rename="setRename" @cancel="cancelDrop">
|
||||||
@overwrite="setOverwrite" @rename="setRename" @cancel="cancelDrop">
|
|
||||||
</FileExistsDialog>
|
</FileExistsDialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// NextCloud Components
|
// NextCloud Components
|
||||||
import { getClient, getRootPath, getFavoriteNodes } from '@nextcloud/files/dav';
|
import { getClient, getRootPath, getFavoriteNodes } from '@nextcloud/files/dav';
|
||||||
@ -190,13 +191,13 @@ export default {
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
|
zip: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
dragEnded: {
|
dragEnded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
|
||||||
translate: {
|
|
||||||
type: Function,
|
|
||||||
Required: true,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -210,7 +211,6 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
trad: null,
|
|
||||||
files: [], // Liste des fichiers et dossiers récupérés
|
files: [], // Liste des fichiers et dossiers récupérés
|
||||||
root_path: getRootPath(),
|
root_path: getRootPath(),
|
||||||
current_dir: '/',
|
current_dir: '/',
|
||||||
@ -363,7 +363,7 @@ export default {
|
|||||||
await this.fetchFiles();
|
await this.fetchFiles();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert(this.translate("cant.create.folder") + this.newFileName + this.translate('already.exists'));
|
alert(`Vous ne pouvez pas creer le dossier : ${this.newFileName} car un autre dossier porte deja le meme nom.`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erreur lors de la création du fichier :', error);
|
console.error('Erreur lors de la création du fichier :', error);
|
||||||
@ -407,10 +407,26 @@ export default {
|
|||||||
try {
|
try {
|
||||||
this.isTransfering = true;
|
this.isTransfering = true;
|
||||||
const file = this.file;
|
const file = this.file;
|
||||||
if (!file) return;
|
const zip = this.zip;
|
||||||
|
console.log(file);
|
||||||
|
console.log(zip);
|
||||||
|
|
||||||
if (file.isList) {
|
if (!file && !zip) return;
|
||||||
await this.moveListOfFiles(file);
|
|
||||||
|
if (zip) {
|
||||||
|
const response = await fetch(zip.url);
|
||||||
|
this.transferProgress = 25;
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Erreur lors du téléchargement : ${response.statusText}`);
|
||||||
|
}
|
||||||
|
const zipFile = await response.arrayBuffer();
|
||||||
|
this.transferProgress = 50;
|
||||||
|
|
||||||
|
await this.moveFileToTarget({
|
||||||
|
name: zip.name,
|
||||||
|
content: zipFile
|
||||||
|
}, '');
|
||||||
|
this.transferProgress = 100;
|
||||||
} else {
|
} else {
|
||||||
if (file.isDirectory) {
|
if (file.isDirectory) {
|
||||||
await this.moveFilesOfFolder(file, '');
|
await this.moveFilesOfFolder(file, '');
|
||||||
@ -424,7 +440,6 @@ export default {
|
|||||||
this.transferProgress = 100;
|
this.transferProgress = 100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isTransfering = false;
|
this.isTransfering = false;
|
||||||
this.transferProgress = 0;
|
this.transferProgress = 0;
|
||||||
this.cancelOperation = false;
|
this.cancelOperation = false;
|
||||||
@ -441,19 +456,6 @@ export default {
|
|||||||
}
|
}
|
||||||
this.isDroppable = true;
|
this.isDroppable = true;
|
||||||
},
|
},
|
||||||
async moveListOfFiles(files) {
|
|
||||||
for (const file of files.children) {
|
|
||||||
this.transferProgress += 100 / files.children.length;
|
|
||||||
if (file.isDirectory) {
|
|
||||||
await this.moveFilesOfFolder(file, file.parentPath + '/');
|
|
||||||
} else {
|
|
||||||
if (file.content && typeof file.content.arrayBuffer === 'function') {
|
|
||||||
file.content = await file.content.arrayBuffer();
|
|
||||||
}
|
|
||||||
await this.moveFileToTarget(file, '');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async moveFilesOfFolder(folder, parentPath) {
|
async moveFilesOfFolder(folder, parentPath) {
|
||||||
await this.createFolder(folder, parentPath + '/');
|
await this.createFolder(folder, parentPath + '/');
|
||||||
const checkChildrenInChildren = (folder) => {
|
const checkChildrenInChildren = (folder) => {
|
||||||
@ -611,7 +613,7 @@ export default {
|
|||||||
await client.moveFile(oldName, newName);
|
await client.moveFile(oldName, newName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert(this.translate('cant.rename') + names.newFileName + this.translate('already.exists'));
|
alert(`Vous ne pouvez pas renommez le fichier/dossier : ${names.newFileName} car un autre fichier/dossier porte deja le meme nom.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
|
@ -1,109 +1,105 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col h-full w-full border">
|
<div class="flex flex-col h-full w-full border">
|
||||||
<!-- Breadcrumb -->
|
<div class="flex h-12 items-center border-b border-gray-300">
|
||||||
<div class="flex flex-row mt-1 items-start container">
|
<div class="w-5/6 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">Nom</div>
|
||||||
<NcBreadcrumbs class="max-h-8">
|
<div class="w-1/6 px-4 py-2 text-gray-500 font-semibold">Taille</div>
|
||||||
<NcBreadcrumb name="Home" title="Title of the Home folder" @click="handleClickBreadcrumb(-1)">
|
|
||||||
</NcBreadcrumb>
|
|
||||||
<NcBreadcrumb v-if="getBreadcrumbParts().length > 0" v-for="(part, index) in breadcrumbParts"
|
|
||||||
:key="index" :name="part" @click="handleClickBreadcrumb(index)">
|
|
||||||
</NcBreadcrumb>
|
|
||||||
</NcBreadcrumbs>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex h-12 items-center border-b border-gray-300">
|
<!-- Fichier .zip -->
|
||||||
<div @click.stop class="flex items-center cursor-pointer">
|
<div class="flex h-16 hover:bg-NcGray items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300" v-if="!isLoading && zipContent.length !== 0"
|
||||||
<input type="checkbox" id="checkbox-file"
|
draggable="true" @dragstart="dragZip()" @dragend="onDragEnd">
|
||||||
class="NIQUE TA MERE CA CHANGE RIEN PARCE QUE HTML/CSS C DE LA MERDE"
|
<template>
|
||||||
@change="handleCheckAll($event)" v-model="checkedAll" />
|
<div class="flex items-center justify-center cursor-pointer">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-10 h-10 ">
|
||||||
|
<path fill="#969696" d="M5.12,5H18.87L17.93,4H5.93L5.12,5M20.54,5.23C20.83,5.57 21,6 21,6.5V19A2,2 0 0,1 19,21H5A2,2 0 0,1 3,19V6.5C3,6 3.17,5.57 3.46,5.23L4.84,3.55C5.12,3.21 5.53,3 6,3H18C18.47,3 18.88,3.21 19.15,3.55L20.54,5.23M6,18H12V15H6V18Z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="w-5/6 flex items-center px-4 py-2 cursor-pointer">
|
||||||
|
<div class="truncate max-sm:max-w-32 max-w-64 cursor-pointer">{{ zipName }}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="w-1/6 py-2 cursor-pointer">
|
||||||
|
{{ formatFileSize(zipSize) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-2 w-5/6 px-4 py-2 text-gray-500 font-semibold border-r border-gray-300">{{
|
|
||||||
translate('name')}}</div>
|
|
||||||
<div class="w-1/6 px-4 py-2 text-gray-500 font-semibold">{{ translate('size') }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Archive depliee -->
|
<!-- Archive depliee -->
|
||||||
<div v-if="!isLoading && zipContent.length !== 0" class="overflow-y-auto h-full">
|
<div v-if="!isLoading && zipContent.length !== 0" class="overflow-y-auto h-full">
|
||||||
<div v-for="(file, index) in cachedSortedFiles" :key="file.fullPath" class="flex flex-col">
|
<div v-for="(file, index) in sortedFiles" :key="file.fullPath" class="flex flex-col">
|
||||||
|
|
||||||
<div class="flex flex-row w-full gap-2">
|
<div class="flex h-16 hover:bg-NcGray items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
||||||
|
:style="{
|
||||||
<div v-if="isVisible(file)" @click.stop class="flex items-center cursor-pointer">
|
'padding-left': `${0.5 * (file.depth + 1)}rem`
|
||||||
<input type="checkbox" id="checkbox-file"
|
}"
|
||||||
class="NIQUE TA MERE SA CHANGE RIEN PARCE QUE HTML/CSS C DE LA MERDE"
|
@click="toggleFolder(file)" v-if="file.isDirectory" draggable="true" @dragstart="onDragStart(file)" @dragend="onDragEnd">
|
||||||
@change="handleCheckboxChange(file, $event)" :checked="isChecked(file)" />
|
<div class="w-5/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
||||||
</div>
|
<div class="w-12 h-12 flex items-center justify-center cursor-pointer">
|
||||||
|
<template>
|
||||||
<div class="flex w-full h-16 dark:hover:bg-NcGray hover:bg-NcWhite items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
<svg fill="currentColor" viewBox="0 0 24 24" class="text-NcBlue w-10 h-10 ">
|
||||||
@click="toggleFolder(file)" v-if="file.isDirectory && isVisible(file)" draggable="true"
|
|
||||||
@dragstart="onDragStart(file)" @dragend="onDragEnd">
|
|
||||||
|
|
||||||
<div class="w-5/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
|
||||||
<div class="w-12 h-12 flex items-center justify-center cursor-pointer">
|
|
||||||
<template>
|
|
||||||
<svg fill="currentColor" viewBox="0 0 24 24" class="text-NcBlue w-10 h-10 ">
|
|
||||||
<path
|
|
||||||
d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
<div class="w-4/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
|
||||||
<span class="ml-2 truncate cursor-pointer">{{ file.name }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-1/6 px-4 py-2 cursor-pointer">-</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="flex h-16 w-full dark:hover:bg-NcGray hover:bg-NcWhite items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
|
||||||
v-else-if="isVisible(file)" draggable="true" @dragstart="onDragStart(file, $event)">
|
|
||||||
<template>
|
|
||||||
<div class="flex items-center justify-center cursor-pointer">
|
|
||||||
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
|
||||||
class="w-10 h-10"
|
|
||||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
|
||||||
<path
|
<path
|
||||||
d="M6 22c-.55 0-1.021-.196-1.412-.587A1.927 1.927 0 0 1 4 20V4c0-.55.196-1.021.588-1.413A1.926 1.926 0 0 1 6 2h8l6 6v12a1.93 1.93 0 0 1-.587 1.413A1.93 1.93 0 0 1 18 22H6Z"
|
d="M10,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V8C22,6.89 21.1,6 20,6H12L10,4Z">
|
||||||
style="fill:#969696;fill-rule:nonzero"
|
</path>
|
||||||
transform="matrix(.7 0 0 .7 -.43 -.388)" />
|
|
||||||
</svg>
|
</svg>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="w-4/6 flex items-center py-2 border-r border-gray-300 cursor-pointer">
|
||||||
|
<!-- Icône dynamique pour plié/déplié -->
|
||||||
|
<div class="w-12 h-12 flex items-center justify-center cursor-pointer">
|
||||||
|
<component :is="folderMap[file.fullPath] ? ChevronDownIcon : ChevronRightIcon"
|
||||||
|
class="text-NcBlue w-6 h-6" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<span class="ml-2 truncate cursor-pointer">{{ file.name }}</span>
|
||||||
<div class="w-5/6 flex items-center px-4 py-2 cursor-pointer">
|
|
||||||
<div class="truncate max-sm:max-w-32 max-w-96 cursor-pointer">{{ file.name }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/6 py-2 cursor-pointer">
|
</div>
|
||||||
{{ formatFileSize(file.size) }}
|
<div class="w-1/6 px-4 py-2 cursor-pointer">-</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex h-16 hover:bg-NcGray items-center pl-4 cursor-pointer rounded-lg border-b last:border-b-0 border-gray-300"
|
||||||
|
:style="{
|
||||||
|
'padding-left': `${0.5 * (file.depth + 1)}rem`
|
||||||
|
}"
|
||||||
|
v-else draggable="true" @dragstart="onDragStart(file, $event)">
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-center cursor-pointer">
|
||||||
|
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xml:space="preserve"
|
||||||
|
class="w-10 h-10"
|
||||||
|
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2">
|
||||||
|
<path
|
||||||
|
d="M6 22c-.55 0-1.021-.196-1.412-.587A1.927 1.927 0 0 1 4 20V4c0-.55.196-1.021.588-1.413A1.926 1.926 0 0 1 6 2h8l6 6v12a1.93 1.93 0 0 1-.587 1.413A1.93 1.93 0 0 1 18 22H6Z"
|
||||||
|
style="fill:#969696;fill-rule:nonzero" transform="matrix(.7 0 0 .7 -.43 -.388)" />
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="w-5/6 flex items-center px-4 py-2 cursor-pointer">
|
||||||
|
<div class="truncate max-sm:max-w-32 max-w-96 cursor-pointer">{{ file.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-1/6 py-2 cursor-pointer">
|
||||||
|
{{ formatFileSize(file.size) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isLoading" class="flex h-full items-center justify-center">
|
<div v-if="isLoading" class="flex h-full items-center justify-center">
|
||||||
<component :is="Loading" class="text-white w-24 h-24 animate-spin" :size="40" />
|
<component :is="Loading" class="text-white w-24 h-24 animate-spin" :size="40" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isLoading && zipContent.length === 0" class="flex h-full items-center justify-center">
|
<div v-if="!isLoading && zipContent.length === 0" class="flex h-full items-center justify-center">
|
||||||
<span class="text-gray-500">{{ translate('no.content') }}</span>
|
<span class="text-gray-500">Aucun contenu à afficher</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NcBreadcrumbs from '@nextcloud/vue/dist/Components/NcBreadcrumbs.js';
|
|
||||||
import NcBreadcrumb from '@nextcloud/vue/dist/Components/NcBreadcrumb.js';
|
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue';
|
import ChevronRightIcon from 'vue-material-design-icons/ChevronRight.vue';
|
||||||
import ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue';
|
import ChevronDownIcon from 'vue-material-design-icons/ChevronDown.vue';
|
||||||
import Loading from 'vue-material-design-icons/Loading.vue';
|
import Loading from 'vue-material-design-icons/Loading.vue';
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import {fileTypeFromBuffer} from 'file-type';
|
import path from 'path';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'WebContentViewer',
|
name: 'WebContentViewer',
|
||||||
components: {
|
|
||||||
NcBreadcrumbs,
|
|
||||||
NcBreadcrumb
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
zipContent: [],
|
zipContent: [],
|
||||||
@ -116,11 +112,6 @@ export default {
|
|||||||
Loading,
|
Loading,
|
||||||
zipName: '',
|
zipName: '',
|
||||||
zipSize: 0,
|
zipSize: 0,
|
||||||
currentDir: '',
|
|
||||||
breadcrumbParts: [],
|
|
||||||
cochedFiles: [],
|
|
||||||
checkedAll: false,
|
|
||||||
cachedSortedFiles: null,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@ -128,12 +119,8 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
translate: {
|
|
||||||
type: Function,
|
|
||||||
Required: true,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed:{
|
computed: {
|
||||||
sortedFiles() {
|
sortedFiles() {
|
||||||
const flattenAndSort = (files, parentPath = '') => {
|
const flattenAndSort = (files, parentPath = '') => {
|
||||||
const flatList = [];
|
const flatList = [];
|
||||||
@ -156,17 +143,10 @@ export default {
|
|||||||
return flatList.sort((a, b) => a.fullPath.localeCompare(b.fullPath));
|
return flatList.sort((a, b) => a.fullPath.localeCompare(b.fullPath));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
return flattenAndSort(this.zipContent);
|
return flattenAndSort(this.zipContent);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
sortedFiles: {
|
|
||||||
handler(newVal) {
|
|
||||||
this.cachedSortedFiles = newVal; // Met à jour la variable chaque fois que sortedFiles change
|
|
||||||
},
|
|
||||||
immediate: true, // Met à jour dès que le composant est monté
|
|
||||||
},
|
|
||||||
},
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
await this.loadZipContent();
|
await this.loadZipContent();
|
||||||
@ -182,103 +162,68 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
async loadZipContent() {
|
async loadZipContent() {
|
||||||
try {
|
try {
|
||||||
var baseUrl = OC.generateUrl('/apps/webtransfer/getZipFile');
|
const response = await fetch(this.zipUrl);
|
||||||
let fullUrl = baseUrl + '?subUrl=' + this.zipUrl;
|
const zipData = await response.blob();
|
||||||
|
this.zipName = this.zipUrl.split('/').pop();
|
||||||
|
const zip = await JSZip.loadAsync(zipData);
|
||||||
|
this.zipSize = zipData.size;
|
||||||
|
|
||||||
let response = await fetch(fullUrl);
|
const files = [];
|
||||||
let responseJson = await response.json();
|
|
||||||
|
|
||||||
const zipData = responseJson.parameters.data;
|
zip.forEach((relativePath, file) => {
|
||||||
const first10Chars = zipData.substring(0,4);
|
const pathParts = relativePath.split('/').filter(Boolean);
|
||||||
|
let currentLevel = files;
|
||||||
|
|
||||||
// Check si le debut du fichier correspond a celui d'un zip
|
for (let i = 0; i < pathParts.length; i++) {
|
||||||
if(first10Chars === 'PK\x03\x04' || first10Chars === 'PK\x05\x06' || first10Chars === 'PK\x07\x08') {
|
const partName = pathParts[i];
|
||||||
this.zipName = this.zipUrl.split('/').pop();
|
const isDirectory = i < pathParts.length - 1 || file.dir;
|
||||||
const zip = await JSZip.loadAsync(zipData);
|
let existing = currentLevel.find(f => f.name === partName && f.isDirectory === isDirectory);
|
||||||
this.zipSize = zipData.size;
|
|
||||||
|
|
||||||
const files = [];
|
let promise;
|
||||||
|
|
||||||
zip.forEach((relativePath, file) => {
|
if (!isDirectory) {
|
||||||
const pathParts = relativePath.split('/').filter(Boolean);
|
promise = file.async("blob").then(content => {
|
||||||
let currentLevel = files;
|
existing.content = content;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 0; i < pathParts.length; i++) {
|
if (!existing) {
|
||||||
const partName = pathParts[i];
|
existing = {
|
||||||
const isDirectory = i < pathParts.length - 1 || file.dir;
|
name: pathParts[i],
|
||||||
let existing = currentLevel.find(f => f.name === partName && f.isDirectory === isDirectory);
|
isDirectory,
|
||||||
|
size: isDirectory ? 0 : file._data.uncompressedSize,
|
||||||
|
content: isDirectory ? null : '', // Initialiser 'content' pour les fichiers
|
||||||
|
children: isDirectory ? [] : null,
|
||||||
|
depth: pathParts.length, // Profondeur du fichier dans l'arborescence
|
||||||
|
//remove the name of the file from the path
|
||||||
|
parentPath: i > 0 ? pathParts[i - 1] : '',
|
||||||
|
unzip: promise
|
||||||
|
};
|
||||||
|
currentLevel.push(existing);
|
||||||
|
}
|
||||||
|
|
||||||
let promise;
|
if (isDirectory) {
|
||||||
|
currentLevel = existing.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (!isDirectory) {
|
// Attendre que tous les contenus de fichier soient extraits
|
||||||
promise = file.async("blob").then(content => {
|
this.zipContent = files;
|
||||||
existing.content = content;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!existing) {
|
// Initialiser folderMap
|
||||||
existing = {
|
const initializeFolderMap = (files, parentPath = '') => {
|
||||||
name: pathParts[i],
|
files.forEach(file => {
|
||||||
isDirectory,
|
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
||||||
size: isDirectory ? 0 : file._data.uncompressedSize,
|
this.$set(this.folderMap, fullPath, false);
|
||||||
content: isDirectory ? null : '', // Initialiser 'content' pour les fichiers
|
if (file.isDirectory && file.children) {
|
||||||
children: isDirectory ? [] : null,
|
initializeFolderMap(file.children, fullPath);
|
||||||
depth: pathParts.length, // Profondeur du fichier dans l'arborescence
|
|
||||||
//remove the name of the file from the path
|
|
||||||
parentPath: i > 0 ? pathParts[i - 1] : '',
|
|
||||||
unzip: promise
|
|
||||||
};
|
|
||||||
currentLevel.push(existing);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDirectory) {
|
|
||||||
currentLevel = existing.children;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Attendre que tous les contenus de fichier soient extraits
|
initializeFolderMap(this.zipContent);
|
||||||
this.zipContent = files;
|
console.log('Contenu du ZIP chargé avec succès');
|
||||||
|
|
||||||
// Initialiser folderMap
|
|
||||||
const initializeFolderMap = (files, parentPath = '') => {
|
|
||||||
files.forEach(file => {
|
|
||||||
const fullPath = parentPath ? `${parentPath}/${file.name}` : file.name;
|
|
||||||
this.$set(this.folderMap, fullPath, false);
|
|
||||||
if (file.isDirectory && file.children) {
|
|
||||||
initializeFolderMap(file.children, fullPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
initializeFolderMap(this.zipContent);
|
|
||||||
console.log('Contenu du ZIP chargé avec succès');
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
const uint8Array = new Uint8Array(zipData.length);
|
|
||||||
for (let i = 0; i <zipData.length; i++) {
|
|
||||||
uint8Array[i] = zipData.charCodeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
let type = await fileTypeFromBuffer(uint8Array);;
|
|
||||||
const file = new File([uint8Array], 'file.' + type.ext, {type: type.mime});
|
|
||||||
let entry = [{
|
|
||||||
name: file.name,
|
|
||||||
isDirectory: false,
|
|
||||||
size: file.size,
|
|
||||||
content: uint8Array, // Initialiser 'content' pour les fichiers
|
|
||||||
children: null,
|
|
||||||
depth: 0, // Profondeur du fichier dans l'arborescence
|
|
||||||
//remove the name of the file from the path
|
|
||||||
parentPath: '',
|
|
||||||
}]
|
|
||||||
this.zipContent = entry;
|
|
||||||
console.log('Fichier chargé avec succès');
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Erreur lors du telechargement du fichier.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erreur lors du chargement du contenu du ZIP :', error);
|
console.error('Erreur lors du chargement du contenu du ZIP :', error);
|
||||||
}
|
}
|
||||||
@ -287,31 +232,7 @@ export default {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.$emit('dragEnded');
|
this.$emit('dragEnded');
|
||||||
},
|
},
|
||||||
handleCheckboxChange(file, event) {
|
|
||||||
if (event.target.checked) {
|
|
||||||
this.cocheFile(file);
|
|
||||||
} else {
|
|
||||||
this.decocheFile(file);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getFullPath(file) {
|
|
||||||
if (!file.parentPath || file.parentPath === '') {
|
|
||||||
return file.name;
|
|
||||||
} else {
|
|
||||||
return `${file.parentPath}/${file.name}`;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cocheFile(file) {
|
|
||||||
if (!this.cochedFiles.some(f => this.getFullPath(f) === this.getFullPath(file))) {
|
|
||||||
this.cochedFiles.push(file);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
decocheFile(file) {
|
|
||||||
this.cochedFiles = this.cochedFiles.filter(f => this.getFullPath(f) !== this.getFullPath(file));
|
|
||||||
},
|
|
||||||
isChecked(file) {
|
|
||||||
return this.cochedFiles.some(f => this.getFullPath(f) === this.getFullPath(file));
|
|
||||||
},
|
|
||||||
formatFileSize(size) {
|
formatFileSize(size) {
|
||||||
if (size < 1024) return `${size} B`;
|
if (size < 1024) return `${size} B`;
|
||||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
|
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)} KB`;
|
||||||
@ -320,33 +241,19 @@ export default {
|
|||||||
},
|
},
|
||||||
toggleFolder(file) {
|
toggleFolder(file) {
|
||||||
if (!file.isDirectory) return;
|
if (!file.isDirectory) return;
|
||||||
this.uncheckAll();
|
|
||||||
const currentState = this.folderMap[file.fullPath];
|
const currentState = this.folderMap[file.fullPath];
|
||||||
const parentPath = file.parentPath;
|
|
||||||
|
|
||||||
if (!currentState) {
|
|
||||||
this.currentDir = file.fullPath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.currentDir = parentPath;
|
|
||||||
}
|
|
||||||
this.$set(this.folderMap, file.fullPath, !currentState);
|
this.$set(this.folderMap, file.fullPath, !currentState);
|
||||||
|
|
||||||
if (parentPath !== '') {
|
|
||||||
const parentState = this.folderMap[parentPath];
|
|
||||||
this.$set(this.folderMap, parentPath, !parentState);
|
|
||||||
}
|
|
||||||
this.breadcrumbParts = this.getBreadcrumbParts()
|
|
||||||
},
|
},
|
||||||
async dragZip() {
|
async dragZip() {
|
||||||
try {
|
try {
|
||||||
const zip = { name: this.zipName, url: this.zipUrl };
|
const zip = {name: this.zipName, url: this.zipUrl};
|
||||||
this.$emit('zip-upload', zip);
|
this.$emit('zip-upload', zip);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Erreur lors du drag du ZIP :', error);
|
console.error('Erreur lors du drag du ZIP :', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async onDragStart(file, event) {
|
async onDragStart(file) {
|
||||||
|
|
||||||
const getFilesFromFolder = (folder) => {
|
const getFilesFromFolder = (folder) => {
|
||||||
const files = [];
|
const files = [];
|
||||||
if (!folder.children || folder.children.length === 0) return files;
|
if (!folder.children || folder.children.length === 0) return files;
|
||||||
@ -362,93 +269,19 @@ export default {
|
|||||||
return files;
|
return files;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.cochedFiles.length > 0) {
|
try {
|
||||||
|
if (file.isDirectory) {
|
||||||
const folder = {
|
const files = getFilesFromFolder(file);
|
||||||
// Si des fichiers sont cochés, utiliser cette liste
|
const filesToUnzip = files.map(file => file.unzip);
|
||||||
name: file.name,
|
await Promise.all(filesToUnzip);
|
||||||
isDirectory: true,
|
} else {
|
||||||
isList: true,
|
await file.unzip;
|
||||||
children: this.cochedFiles,
|
|
||||||
unzip: Promise.all(this.cochedFiles.map(file => file.unzip))
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
await folder.unzip;
|
|
||||||
this.$emit('file-upload', folder);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erreur lors du drag start :', error);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Logique existante pour un seul fichier/dossier
|
|
||||||
try {
|
|
||||||
if (file.isDirectory) {
|
|
||||||
const files = getFilesFromFolder(file);
|
|
||||||
const filesToUnzip = files.map(file => file.unzip);
|
|
||||||
await Promise.all(filesToUnzip);
|
|
||||||
} else {
|
|
||||||
await file.unzip;
|
|
||||||
}
|
|
||||||
this.$emit('file-upload', file);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Erreur lors du drag start :', error);
|
|
||||||
}
|
}
|
||||||
|
this.$emit('file-upload', file);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors du drag start :', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isVisible(file) {
|
|
||||||
let parentPath = file.parentPath;
|
|
||||||
if (this.currentDir === parentPath) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getBreadcrumbParts() {
|
|
||||||
// Si le currentDir est un simple '/', on le renvoie sous forme de tableau vide.
|
|
||||||
if (this.currentDir === '') return [];
|
|
||||||
return this.currentDir.split('/').filter(part => part);
|
|
||||||
},
|
|
||||||
generateCrumbHref(index) {
|
|
||||||
const parts = this.breadcrumbParts.slice(0, index + 1);
|
|
||||||
return parts.join('/');
|
|
||||||
},
|
|
||||||
handleClickBreadcrumb(index) {
|
|
||||||
this.uncheckAll();
|
|
||||||
if (this.isTransfering) return;
|
|
||||||
let dir = '';
|
|
||||||
if (index >= -1) {
|
|
||||||
dir = this.generateCrumbHref(index);
|
|
||||||
}
|
|
||||||
this.currentDir = dir;
|
|
||||||
this.breadcrumbParts = this.getBreadcrumbParts();
|
|
||||||
let file = {
|
|
||||||
fullPath: dir,
|
|
||||||
parentPath: this.generateCrumbHref(index - 1),
|
|
||||||
isDirectory: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.keys(this.folderMap).forEach(key => {
|
|
||||||
this.folderMap[key] = false;
|
|
||||||
});
|
|
||||||
this.toggleFolder(file)
|
|
||||||
},
|
|
||||||
uncheckAll() {
|
|
||||||
this.cochedFiles = [];
|
|
||||||
this.checkedAll = false;
|
|
||||||
},
|
|
||||||
handleCheckAll(event) {
|
|
||||||
this.sortedFiles.forEach(file => {
|
|
||||||
if(this.isVisible(file)) {
|
|
||||||
if (event.target.checked) {
|
|
||||||
this.cocheFile(file);
|
|
||||||
} else {
|
|
||||||
this.decocheFile(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -4,14 +4,12 @@ module.exports = {
|
|||||||
"./src/**/*.{html,js,jsx,vue}", // Fichiers dans le dossier `src`
|
"./src/**/*.{html,js,jsx,vue}", // Fichiers dans le dossier `src`
|
||||||
"./templates/**/*.{html,php}", // Fichiers dans le dossier `templates`
|
"./templates/**/*.{html,php}", // Fichiers dans le dossier `templates`
|
||||||
],
|
],
|
||||||
darkMode: ['selector', ':is([data-themes="dark"], [data-themes="dark-highcontrast"], [data-themes="default"])'],
|
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
NcBlack: '#171717',
|
NcBlack: '#171717',
|
||||||
NcBlue: '#0072c3',
|
NcBlue: '#0072c3',
|
||||||
NcGray: '#212121',
|
NcGray: '#212121',
|
||||||
NcWhite: '#ededed',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -7,12 +7,14 @@ use OCP\Util;
|
|||||||
Util::addScript(OCA\WebTransfer\AppInfo\Application::APP_ID, 'main');
|
Util::addScript(OCA\WebTransfer\AppInfo\Application::APP_ID, 'main');
|
||||||
|
|
||||||
$archiveUrl = isset($_['archiveUrl']) ? $_['archiveUrl'] : ''; // Valeur par défaut vide si non définie
|
$archiveUrl = isset($_['archiveUrl']) ? $_['archiveUrl'] : ''; // Valeur par défaut vide si non définie
|
||||||
|
$token = isset($_['token']) ? $_['token'] : ''; // Valeur par défaut vide si non définie
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div id="webtransfer">
|
<div id="webtransfer">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="archiveInfos"
|
<div id="archiveInfos"
|
||||||
dataarchiveurl="<?php echo htmlspecialchars($archiveUrl); ?>"
|
data-archive-url="<?php echo htmlspecialchars($archiveUrl); ?>"
|
||||||
|
data-token="<?php echo htmlspecialchars($token); ?>"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user