Compare commits

..

44 Commits

Author SHA1 Message Date
Julius Härtl
a0ffc3a47f Make 0.3.1-rc1
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 19:33:02 +01:00
Julius Härtl
bb3b31f38f No typehinting in deck yet
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 19:31:43 +01:00
Julius Härtl
cae999ec80 Fix tests
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 19:31:43 +01:00
Julius Härtl
9273d15865 Update view when removing sharees and track by correct property
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 19:31:43 +01:00
Julius Härtl
5d40ecad25 Remove deleted users from assignments
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 19:31:42 +01:00
Nextcloud bot
5e4b3b9218 [tx-robot] updated from transifex 2018-03-02 18:01:21 +01:00
Nextcloud bot
9f154e6ab1 [tx-robot] updated from transifex 2018-03-02 18:01:14 +01:00
Julius Härtl
cdb3193d9c Disable integration tests for now
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:59:24 +01:00
Julius Härtl
0200179a76 Do not overwrite emtpy values
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:59:24 +01:00
Julius Härtl
b1863980d6 Track by correct property
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:59:23 +01:00
Julius Härtl
087d60776d Only return updated properties not resolvable ones
fixes #406

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:59:23 +01:00
Julius Härtl
e859c6aa56 Fix popover position of assigned users
fixes #385

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:59:23 +01:00
Julius Härtl
6a098dd981 Add confirmation dialog to delete options
this is only a temporary solution but it will probably safe some users from deleting their data by accident

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-03-02 17:58:09 +01:00
Julius Härtl
7b47414a54 Add changes to CHANGELOG.md
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 11:07:17 +01:00
Julius Härtl
07ec3fd7d0 Add 0.3.1 version/dependencies
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 11:02:25 +01:00
Nextcloud bot
0af3c87d91 [tx-robot] updated from transifex 2018-02-25 11:01:10 +01:00
Nextcloud bot
c789a6356a [tx-robot] updated from transifex 2018-02-25 11:01:10 +01:00
Nextcloud bot
09c3f4e46d [tx-robot] updated from transifex 2018-02-25 11:01:09 +01:00
Nextcloud bot
a72a11584d [tx-robot] updated from transifex 2018-02-25 11:01:09 +01:00
Nextcloud bot
c850e8b1c2 [tx-robot] updated from transifex 2018-02-25 11:01:08 +01:00
Nextcloud bot
6b06f4e5e8 [tx-robot] updated from transifex 2018-02-25 11:01:08 +01:00
Nextcloud bot
52db1dc37c [tx-robot] updated from transifex 2018-02-25 11:01:07 +01:00
Nextcloud bot
8837d89503 [tx-robot] updated from transifex 2018-02-25 11:01:07 +01:00
Nextcloud bot
640db050bd [tx-robot] updated from transifex 2018-02-25 11:01:06 +01:00
Nextcloud bot
0c4ae1b913 [tx-robot] updated from transifex 2018-02-25 11:01:06 +01:00
Nextcloud bot
4b5ac63d2b [tx-robot] updated from transifex 2018-02-25 11:01:05 +01:00
Nextcloud bot
1a9c5225e1 [tx-robot] updated from transifex 2018-02-25 11:01:05 +01:00
Nextcloud bot
b74916d1f2 [tx-robot] updated from transifex 2018-02-25 11:01:04 +01:00
Nextcloud bot
86bcedd3ca [tx-robot] updated from transifex 2018-02-25 11:01:04 +01:00
Nextcloud bot
e998c3d927 [tx-robot] updated from transifex 2018-02-25 11:01:04 +01:00
Nextcloud bot
43241921e5 [tx-robot] updated from transifex 2018-02-25 11:01:03 +01:00
Nextcloud bot
13cf7fe7f2 [tx-robot] updated from transifex 2018-02-25 11:01:02 +01:00
Julius Härtl
475ecc3c2a Force limit of users that do not match exactly
fixes #422

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:57:50 +01:00
Julius Härtl
c1425f7a4b Update user list when acl is changed
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:57:20 +01:00
Julius Härtl
111ff4ae7f Use actual acl list for assigning users
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:57:20 +01:00
Julius Härtl
b7ac7067ff Fix bug when user selection was staying hidden
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:57:20 +01:00
Julius Härtl
3d634ffdcb Only digest on card update not for every interval
and add various track by statements

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:54:56 +01:00
Julius Härtl
30eeaf8ffd Add Repo as homepage (fixes #389)
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-02-25 10:53:45 +01:00
Julius Härtl
6594a3f5da Merge branch 'fix-app-compatibility' into stable-0.3 2018-02-25 10:53:16 +01:00
Julius Härtl
58df42ea9c Bump drone images (#391)
* Bump drone images

Signed-off-by: Julius Härtl <jus@bitgrid.net>

* Use travis for codecov

Signed-off-by: Julius Härtl <jus@bitgrid.net>

* Just test against master in travis

Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-01-13 12:29:29 +01:00
cloud2018
169175ab55 translate attributes in templates/part.card.php
translate attributes title and placeholder in class "section-content card-details-assign-users" in templates/part.card.php
2018-01-13 12:28:47 +01:00
Julius Härtl
f2b94f0933 Just test against master in travis
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-01-13 11:48:21 +01:00
Julius Härtl
2fece55b0e Use travis for codecov
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-01-13 11:37:48 +01:00
Julius Härtl
f34fae640d Bump drone images
Signed-off-by: Julius Härtl <jus@bitgrid.net>
2018-01-13 10:39:40 +01:00
560 changed files with 13972 additions and 84535 deletions

213
.drone.yml Normal file
View File

@@ -0,0 +1,213 @@
clone:
git:
image: plugins/git
depth: 1
pipeline:
check-app-compatbility:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server
# Code checker
- ./occ app:check-code $APP_NAME -c strong-comparison
- ./occ app:check-code $APP_NAME -c deprecation
- cd apps/$APP_NAME/
when:
matrix:
TESTS: check-app-compatbility
signed-off-check:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- wget https://raw.githubusercontent.com/nextcloud/server/master/build/signed-off-checker.php
- php ./signed-off-checker.php
when:
matrix:
TESTS: signed-off-check
syntax-php5.6:
image: nextcloudci/php5.6:php5.6-8
environment:
- APP_NAME=deck
- CORE_BRANCH=stable13
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php5.6
syntax-php7.0:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.0
syntax-php7.1:
image: nextcloudci/php7.1:php7.1-15
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.1
syntax-php7.2:
image: nextcloudci/php7.2:php7.2-9
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
- composer install
- ./vendor/bin/parallel-lint --exclude ./vendor/ .
when:
matrix:
TESTS: syntax-php7.2
php5.6:
image: nextcloudci/php5.6:php5.6-8
environment:
- APP_NAME=deck
- CORE_BRANCH=stable13
- DB=sqlite
commands:
- apt update && apt-get -y install php5-xdebug
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- ./occ app:enable $APP_NAME
- cd apps/$APP_NAME
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php5.6
php7.0:
image: nextcloudci/php7.0:php7.0-17
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
# Run phpunit tests
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php7.0
php7.1:
image: nextcloudci/php7.1:php7.1-15
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php7.1
php7.2:
image: nextcloudci/php7.2:php7.2-9
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
- phpunit -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
- phpunit -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
when:
matrix:
TESTS: php7.2
integration:
image: nextcloudci/integration-php7.0:integration-php7.0-6
environment:
- APP_NAME=deck
- CORE_BRANCH=master
- DB=sqlite
commands:
# Pre-setup steps
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh $APP_NAME $CORE_BRANCH $DB
- cd ../server/
- php occ app:enable deck
- cd apps/$APP_NAME
- cd tests/integration
- ./run.sh
when:
matrix:
TESTS: integration
eslint:
image: nextcloudci/eslint:eslint-1
commands:
- ./run-eslint.sh
when:
matrix:
TESTS: eslint
jsbuild:
image: mhart/alpine-node:6.8.0
commands:
- apk add --no-cache git
- cd js
- npm install --deps
- ./node_modules/.bin/bower --allow-root install
when:
matrix:
TESTS: jsbuild
matrix:
include:
- TESTS: check-app-compatbility
- TESTS: signed-off-check
- TESTS: syntax-php5.6
- TESTS: syntax-php7.0
- TESTS: syntax-php7.1
- TESTS: syntax-php7.2
- TESTS: php5.6
- TESTS: php7.0
- TESTS: php7.1
- TESTS: php7.2
- TESTS: eslint
- TESTS: jsbuild
#- TESTS: integration
branches: [ master, stable* ]

View File

@@ -1,9 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
[*.{js,vue}]
indent_style = tab

View File

@@ -1,6 +1,5 @@
/js/tests/*
/js/vendor/*
/js/legacy/*
/js/node_modules/*
/js/public/*
/karma.conf.js

View File

@@ -1,8 +0,0 @@
module.exports = {
extends: [
'@nextcloud'
],
rules: {
'valid-jsdoc': ['off'],
}
}

37
.eslintrc.yml Normal file
View File

@@ -0,0 +1,37 @@
root: true
extends:
- eslint:recommended
env:
browser: true
amd: true
globals:
app: false
angular: false
$: false
escapeHTML: false
OC: false
OCA: false
t: false
oc_current_user: false
oc_requesttoken: false
Clipboard: false
oc_defaults: false
rules:
curly: error
eqeqeq: ["error", "smart"]
guard-for-in: error
no-console: off
no-fallthrough: error
no-mixed-spaces-and-tabs: error
no-unused-vars: warn
no-use-before-define: error
semi: ["error", "always"]
indent:
- error
- tab
- SwitchCase: 1

View File

@@ -1,120 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
---
<!--
Thanks for reporting issues back!
Guidelines for submitting issues:
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
* SECURITY: Report any potential security bug to us via our HackerOne page (https://hackerone.com/nextcloud) following our security policy (https://nextcloud.com/security/) instead of filing an issue in our bug tracker.
* The issues in other components should be reported in their respective repositories: You will find them in our GitHub Organization (https://github.com/nextcloud/)
* You can also use the Issue Template app to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
-->
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Client details:**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
- Device: [e.g. iPhone6, desktop]
<details>
<summary>Server details</summary>
<!--
You can use the Issue Template application to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
-->
**Operating system**:
**Web server:**
**Database:**
**PHP version:**
**Nextcloud version:** (see Nextcloud admin page)
**Where did you install Nextcloud from:**
**Signing status:**
```
Login as admin user into your Nextcloud and access
http://example.com/index.php/settings/integrity/failed
paste the results here.
```
**List of activated apps:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ app:list
from within your Nextcloud installation folder
```
**Nextcloud configuration:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ config:list system
from within your Nextcloud installation folder
or
Insert your config.php content here
Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …)
```
**Are you using an external user-backend, if yes which one:** LDAP/ActiveDirectory/Webdav/...
</details>
<details>
<summary>Logs</summary>
#### Nextcloud log (data/nextcloud.log)
```
Insert your Nextcloud log here
```
#### Browser log
```
Insert your browser log here, this could for example include:
a) The javascript console log
b) The network log
c) ...
```
</details>

View File

@@ -1,39 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
---
<!--
Thanks for reporting issues back!
Guidelines for submitting issues:
* Please search the existing issues first, it's likely that your issue was already reported or even fixed.
* SECURITY: Report any potential security bug to us via our HackerOne page (https://hackerone.com/nextcloud) following our security policy (https://nextcloud.com/security/) instead of filing an issue in our bug tracker.
* The issues in other components should be reported in their respective repositories: You will find them in our GitHub Organization (https://github.com/nextcloud/)
* You can also use the Issue Template app to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
-->
<!--- Please keep this note for other contributors -->
### How to use GitHub
* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are affected by the same issue.
* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
* Subscribe to receive notifications on status change and new comments.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,41 +0,0 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
target-branch: "master"
schedule:
interval: weekly
day: saturday
time: "03:00"
timezone: Europe/Paris
open-pull-requests-limit: 10
reviewers:
- juliushaertl
- jakobroehrl
#- package-ecosystem: npm
# directory: "/"
# target-branch: "stable1.1"
# schedule:
# interval: weekly
# day: saturday
# time: "03:00"
# timezone: Europe/Paris
# open-pull-requests-limit: 10
# reviewers:
# - juliushaertl
# - jakobroehrl
- package-ecosystem: composer
directory: "/"
schedule:
interval: weekly
day: saturday
time: "03:00"
timezone: Europe/Paris
open-pull-requests-limit: 10
reviewers:
- juliushaertl
ignore:
- dependency-name: christophwurst/nextcloud
versions:
- "< 16"
- ">= 15.a"

View File

@@ -1,17 +0,0 @@
* Resolves: # <!-- related github issue -->
* Target version: master
### Summary
### TODO
- [ ] ...
### Checklist
- [ ] Code is properly formatted
- [ ] Sign-off message is added to all commits
- [ ] Tests (unit, integration, api and/or acceptance) are included
- [ ] Documentation (manuals or wiki) has been updated or is not required

25
.github/stale.yml vendored
View File

@@ -1,25 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- "1. to develop"
- "2. developing"
- "3. to review"
- "discussion"
- "bounty"
- "bug"
- "enhancement"
# Limit the number of actions per hour, from 1-30. Default is 30
limitPerRun: 30
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.

View File

@@ -1,37 +0,0 @@
name: Package build
on:
pull_request:
jobs:
build:
runs-on: ubuntu-18.04
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: '7.4'
tools: composer
- name: install dependencies
run: |
wget https://github.com/ChristophWurst/krankerl/releases/download/v0.12.2/krankerl_0.12.2_amd64.deb
sudo dpkg -i krankerl_0.12.2_amd64.deb
- name: package
run: |
uname -a
RUST_BACKTRACE=1 krankerl --version
RUST_BACKTRACE=1 krankerl package
- uses: actions/upload-artifact@v2
with:
name: Deck app tarball
path: build/artifacts/deck.tar.gz

View File

@@ -1,91 +0,0 @@
name: Integration tests
on:
pull_request:
push:
branches:
- master
- stable*
env:
APP_NAME: deck
jobs:
integration:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php-versions: ['7.4']
databases: ['sqlite', 'mysql', 'pgsql']
server-versions: ['master']
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
services:
postgres:
image: postgres
ports:
- 4445:5432/tcp
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: rootpassword
POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
mysql:
image: mariadb:10.5
ports:
- 4444:3306/tcp
env:
MYSQL_ROOT_PASSWORD: rootpassword
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5
steps:
- name: Checkout server
uses: actions/checkout@v2
with:
repository: nextcloud/server
ref: ${{ matrix.server-versions }}
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Checkout app
uses: actions/checkout@v2
with:
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: phpunit
extensions: mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql,
coverage: none
- name: Set up PHPUnit
working-directory: apps/${{ env.APP_NAME }}
run: composer i
- name: Set up Nextcloud
run: |
if [ "${{ matrix.databases }}" = "mysql" ]; then
export DB_PORT=4444
elif [ "${{ matrix.databases }}" = "pgsql" ]; then
export DB_PORT=4445
fi
mkdir data
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
cat config/config.php
./occ user:list
./occ app:enable --force ${{ env.APP_NAME }}
php -S localhost:8080 &
- name: Run behat
working-directory: apps/${{ env.APP_NAME }}/tests/integration
run: ./run.sh

View File

@@ -1,83 +0,0 @@
name: Lint
on:
pull_request:
push:
branches:
- master
- stable*
jobs:
php:
runs-on: ubuntu-latest
strategy:
matrix:
php-versions: ['7.2', '7.3', '7.4']
name: php${{ matrix.php-versions }} lint
steps:
- uses: actions/checkout@v2
- name: Set up php${{ matrix.php-versions }}
uses: shivammathur/setup-php@v1
with:
php-version: ${{ matrix.php-versions }}
coverage: none
- name: Lint
run: composer run lint
php-cs-fixer:
name: php-cs check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set up php
uses: shivammathur/setup-php@master
with:
php-version: 7.4
coverage: none
- name: Install dependencies
run: composer i
- name: Run coding standards check
run: composer run cs:check
node:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v2
- name: Use node ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: ESLint
run: npm run lint
stylelint:
runs-on: ubuntu-latest
strategy:
matrix:
node-versions: [12.x]
name: stylelint node${{ matrix.node-versions }}
steps:
- uses: actions/checkout@v2
- name: Set up node ${{ matrix.node-versions }}
uses: actions/setup-node@v1
with:
node-versions: ${{ matrix.node-versions }}
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run stylelint

View File

@@ -1,62 +0,0 @@
name: Package nightly
on:
push:
branches:
- nightly
schedule:
- cron: '0 1 * * *' # run at 2 AM UTC
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: '7.4'
tools: composer
- name: install dependencies
run: |
wget https://github.com/ChristophWurst/krankerl/releases/download/v0.12.2/krankerl_0.12.2_amd64.deb
sudo dpkg -i krankerl_0.12.2_amd64.deb
- name: package
run: |
uname -a
RUST_BACKTRACE=1 krankerl --version
RUST_BACKTRACE=1 krankerl package
- name: Set git config
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git tag -f nightly
- name: Push tag
uses: juliushaertl/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
tags: true
force: true
- name: Create Release
id: create_release
uses: juliushaertl/action-release@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag: nightly
files: ./build/artifacts/deck.tar.gz
name: Nightly build
body: |
Nightly release of deck
draft: false
prerelease: true
overwrite: true

View File

@@ -1,32 +0,0 @@
name: Node CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x]
steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: install dependencies
run: |
npm ci
- name: build
env:
RELATIVE_CI_KEY: ${{ secrets.RELATIVE_CI_KEY }}
RELATIVE_CI_SLUG: nextcloud/deck
run: |
mkdir -p js
npm run build --if-present -- --profile --json | tail -n +6 > js/webpack-stats.json
npx relative-ci-agent

View File

@@ -1,94 +0,0 @@
name: PHPUnit
on:
pull_request:
push:
branches:
- master
- stable*
env:
APP_NAME: deck
jobs:
integration:
runs-on: ubuntu-18.04
strategy:
fail-fast: false
matrix:
php-versions: ['7.3', '7.4']
databases: ['sqlite', 'mysql', 'pgsql']
server-versions: ['master']
name: php${{ matrix.php-versions }}-${{ matrix.databases }}-${{ matrix.server-versions }}
services:
postgres:
image: postgres
ports:
- 4445:5432/tcp
env:
POSTGRES_USER: root
POSTGRES_PASSWORD: rootpassword
POSTGRES_DB: nextcloud
options: --health-cmd pg_isready --health-interval 5s --health-timeout 2s --health-retries 5
mysql:
image: mariadb:10.5
ports:
- 4444:3306/tcp
env:
MYSQL_ROOT_PASSWORD: rootpassword
options: --health-cmd="mysqladmin ping" --health-interval 5s --health-timeout 2s --health-retries 5
steps:
- name: Checkout server
uses: actions/checkout@v2
with:
repository: nextcloud/server
ref: ${{ matrix.server-versions }}
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1
- name: Checkout app
uses: actions/checkout@v2
with:
path: apps/${{ env.APP_NAME }}
- name: Set up php ${{ matrix.php-versions }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
tools: phpunit
extensions: zip, gd, mbstring, iconv, fileinfo, intl, sqlite, pdo_sqlite, mysql, pdo_mysql, pgsql, pdo_pgsql
coverage: none
- name: Set up PHPUnit
working-directory: apps/${{ env.APP_NAME }}
run: composer i
- name: Set up Nextcloud
run: |
if [ "${{ matrix.databases }}" = "mysql" ]; then
export DB_PORT=4444
elif [ "${{ matrix.databases }}" = "pgsql" ]; then
export DB_PORT=4445
fi
mkdir data
./occ maintenance:install --verbose --database=${{ matrix.databases }} --database-name=nextcloud --database-host=127.0.0.1 --database-port=$DB_PORT --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
./occ app:enable --force ${{ env.APP_NAME }}
php -S localhost:8080 &
- name: PHPUnit
working-directory: apps/${{ env.APP_NAME }}
run: ./vendor/phpunit/phpunit/phpunit -c tests/phpunit.xml
- name: PHPUnit integration
working-directory: apps/${{ env.APP_NAME }}
run: ./vendor/phpunit/phpunit/phpunit -c tests/phpunit.integration.xml

View File

@@ -1,31 +0,0 @@
name: Static analysis
on:
pull_request:
push:
branches:
- master
- stable*
jobs:
static-psalm-analysis:
runs-on: ubuntu-latest
strategy:
matrix:
ocp-version: [ 'dev-master' ]
name: Nextcloud ${{ matrix.ocp-version }}
steps:
- name: Checkout
uses: actions/checkout@master
- name: Set up php
uses: shivammathur/setup-php@master
with:
php-version: 7.4
tools: composer:v1
coverage: none
- name: Install dependencies
run: composer i
- name: Install dependencies
run: composer require --dev christophwurst/nextcloud:${{ matrix.ocp-version }}
- name: Run coding standards check
run: composer run psalm

11
.gitignore vendored
View File

@@ -1,11 +1,10 @@
node_modules/*
js/
js/node_modules/*
js/vendor/
js/public/
js/package-lock.json
build/
css/style.css
css/vendor.css
tests/integration/vendor/
tests/integration/composer.lock
tests/.phpunit.result.cache
vendor/
.php_cs.cache
\.idea/
*.lock

View File

@@ -1,28 +0,0 @@
/build/
/.git
/.github
/docs/
/tests
/babel.config.js
/.editorconfig
/.eslintrc.js
/.nextcloudignore
/webpack.*.js
/.codecov.yml
/composer.json
/composer.lock
/_config.yml
/.drone.yml
/.travis.yml
/.eslintignore
/.eslintrc.yml
/.gitignore
/issue_template.md
/krankerl.toml
/Makefile
/mkdocs.yml
/run-eslint.sh
/package.json
/package-lock.json
/node_modules/
/src/

View File

@@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
require_once './vendor/autoload.php';
use Nextcloud\CodingStandard\Config;
$config = new Config();
$config
->getFinder()
// ->ignoreVCSIgnored(true)
->notPath('build')
->notPath('l10n')
->notPath('src')
->notPath('node_modules')
->notPath('vendor')
->in(__DIR__);
return $config;

36
.travis.yml Normal file
View File

@@ -0,0 +1,36 @@
language: php
services:
- mysql
php:
- 7.0
- 7.1
- 7.2
env:
- CORE_BRANCH=master DB=mysql
before_install:
- wget https://phar.phpunit.de/phpunit-5.7.phar
- chmod +x phpunit-5.7.phar
- mkdir bin
- mv phpunit-5.7.phar bin/phpunit
- export PATH="$PWD/bin:$PATH"
- phpunit --version
- wget https://raw.githubusercontent.com/nextcloud/travis_ci/master/before_install.sh
- bash ./before_install.sh deck $CORE_BRANCH $DB
- cd ../server
- ./occ app:enable deck
before_script:
- cd apps/deck
script:
- make test-unit
after_success:
- bash <(curl -s https://codecov.io/bash)
after_failure:
- cat ../../data/nextcloud.log
notifications:
email: false

View File

@@ -1,470 +1,17 @@
# Changelog
All notable changes to this project will be documented in this file.
## 1.4.7
## 0.3.1 - unreleased
### Fixed
- Fix performance issue with large LDAP instances
- Fix assigning users to newly created boards
- Various performance improvements
- Fix some untranslated strings (@cloud2018)
- Add confirmation dialog to delete options
- Fix issues with assigned users list when saving a card
- Delete assignments if users get removed
- Fix release asset build
## 1.4.6
### Fixed
- #3379 Fix menu button position in card modal
- #3360 Improve combined search @eneiluj
- #3367 Fix optional parameter order
- #3393 Use displayname instead of uid for mentions
- #3359 Rich object string parameters for notifications @juliushaertl
- #3385 Extend drag-and-drop zone in card sidebar @Artem4590
- #3408 Keep exceptions http response generic
## 1.4.5
### Fixed
- #3318 Additional check for stacks
## 1.4.4
### Fixed
- #3301 Fix print style issues
- #3307 Return false instead of throwing when getting calendar setting
- #3227 Additional circle level check
- #3304 Delete file shares through attachments API
## 1.4.3 - 2021-07-09
### Fixed
* [#3143](https://github.com/nextcloud/deck/pull/3143) Always pass user id in share provider
* [#3153](https://github.com/nextcloud/deck/pull/3153) Only offer stack creation in emptycontent with proper permissions
* [#3164](https://github.com/nextcloud/deck/pull/3164) Always log generic exceptions
* [#3169](https://github.com/nextcloud/deck/pull/3169) Reduce duplicate queries when fetching user boards an permissions
## 1.4.2 - 2021-05-03
### Fixed
* [#3030](https://github.com/nextcloud/deck/pull/3030) Proper error handling when fetching comments fails
* [#3031](https://github.com/nextcloud/deck/pull/3031) Allow searching for filters without a query to match all that have a given filter set
* [#3039](https://github.com/nextcloud/deck/pull/3039) Catch any error during circle detail fetching
* [#3040](https://github.com/nextcloud/deck/pull/3040) Get attachment from the user node instead of the share source
## 1.4.1 - 2021-04-20
### Fixed
* [#2984](https://github.com/nextcloud/deck/pull/2984) Fix codemirror description width
* [#2990](https://github.com/nextcloud/deck/pull/2990) Fix unified comments search with postgres
* [#2994](https://github.com/nextcloud/deck/pull/2994) Remove notification on unshare and add type hints
* [#3006](https://github.com/nextcloud/deck/pull/3006) Only import debounce
* [#3008](https://github.com/nextcloud/deck/pull/3008) Do not query the lookupserver when looking for sharees
## 1.4.0 - 2021-04-13
### Added
* [#2934](https://github.com/nextcloud/deck/pull/2934) Advanced search queries (see [documentation](https://deck.readthedocs.io/en/latest/User_documentation_en/#search) for more details)
* [#2933](https://github.com/nextcloud/deck/pull/2933) Move full text search to proper events
### Fixed
* [#2964](https://github.com/nextcloud/deck/pull/2964) Fix navigating to board details
* Dependency updates
## 1.3.0
### Added
* [#2638](https://github.com/nextcloud/deck/pull/2638) Sharing files to cards
* [#2683](https://github.com/nextcloud/deck/pull/2683) Handle clicks on calendar entries
* Nextcloud 21 compatiblity
### Fixed
* [#2622](https://github.com/nextcloud/deck/pull/2622) Fix gradient and stack header spacing for safari
* [#2626](https://github.com/nextcloud/deck/pull/2626) Adding a description icon to cards when they contain a description without any checkmarks @MonkeySon
* [#2659](https://github.com/nextcloud/deck/pull/2659) Matching color of description cursor with text color @JonFStr
* [#2676](https://github.com/nextcloud/deck/pull/2676) Only load filter view when shown
* [#2680](https://github.com/nextcloud/deck/pull/2680) Do not try to add change data if it doesn't exist
* [#2681](https://github.com/nextcloud/deck/pull/2681) Filter out deleted stacks from results
* [#2685](https://github.com/nextcloud/deck/pull/2685) Show all boards in move card dialog @jakobroehrl
* [#2687](https://github.com/nextcloud/deck/pull/2687) 3dots no opacity @jakobroehrl
* [#2688](https://github.com/nextcloud/deck/pull/2688) Title > boardname @jakobroehrl
* [#2689](https://github.com/nextcloud/deck/pull/2689) Modal > bigger view wording @jakobroehrl
## 1.3.0-beta2
### Fixed
* [#2700](https://github.com/nextcloud/deck/pull/2700) Attempt to copy file on dropping it to deck @juliushaertl
* [#2701](https://github.com/nextcloud/deck/pull/2701) Fix uploading files by drag and drop @juliushaertl
* [#2707](https://github.com/nextcloud/deck/pull/2707) L10n: Change to a capital letter @Valdnet
* [#2712](https://github.com/nextcloud/deck/pull/2712) Docs: Fix table in section "GET /api/v1.0/config" @das-g
* [#2716](https://github.com/nextcloud/deck/pull/2716) Remove repair step which is no longer needed as we cleanup properly @juliushaertl
* [#2723](https://github.com/nextcloud/deck/pull/2723) Pad random color with leading zeroes @PVince81
* [#2729](https://github.com/nextcloud/deck/pull/2729) Remove invalid activity parameters @nickvergessen
* [#2750](https://github.com/nextcloud/deck/pull/2750) Fix deck activity emails not being translated @nickvergessen
* [#2751](https://github.com/nextcloud/deck/pull/2751) Properly set author for activity events that are triggered by cron @juliushaertl
## 1.2.2 - 2020-11-24
### Fixed
* [#2584](https://github.com/nextcloud/deck/pull/2584) Fix updating checkbox state and avoid issues due to duplicate sidebar element
* [#2586](https://github.com/nextcloud/deck/pull/2586) Fix card details button
* [#2587](https://github.com/nextcloud/deck/pull/2587) Move modal top spacing to the header to avoid side-effect when scrolling
* [#2588](https://github.com/nextcloud/deck/pull/2588) Do not render images in editor
* [#2609](https://github.com/nextcloud/deck/pull/2609) Fix issue with depenendency causing newline comments to not show
* [#2611](https://github.com/nextcloud/deck/pull/2611) Fix paragraph styling in comments
## 1.2.1 - 2020-11-18
### Fixed
* [#2570](https://github.com/nextcloud/deck/pull/2570) [#2571](https://github.com/nextcloud/deck/pull/2571) Fix error when deleting users @ksteinb
* [#2573](https://github.com/nextcloud/deck/pull/2573) Fix issue where card description was changed on the wrong card when switching cards
## 1.2.0 - 2020-11-16
### Added
* [#2430](https://github.com/nextcloud/deck/pull/2430) Due date notification setting per board
* [#2230](https://github.com/nextcloud/deck/pull/2230) Implement scrolling per stack
* [#1396](https://github.com/nextcloud/deck/pull/1396) API: Expose canCreateBoards through capabilities
* [#2245](https://github.com/nextcloud/deck/pull/2245) API: ETag support for API endpoints
### Fixed
* [#2330](https://github.com/nextcloud/deck/pull/2330) Enhanced undo handling for deletions @jakobroehrl
* [#2336](https://github.com/nextcloud/deck/pull/2336) Run unit tests on github actions
* [#2358](https://github.com/nextcloud/deck/pull/2358) Properly check if FTSEvent has an argument set
* [#2359](https://github.com/nextcloud/deck/pull/2359) Also exclude deleted items from calendar boards
* [#2361](https://github.com/nextcloud/deck/pull/2361) Comments do not depend on the comments app @jakobroehrl
* [#2363](https://github.com/nextcloud/deck/pull/2363) Use uid instead of displayname for sharee results
* [#2367](https://github.com/nextcloud/deck/pull/2367) Properly handle multiple shares in a row and refactor sharee loading
* [#2404](https://github.com/nextcloud/deck/pull/2404) Update Controls.vue @Flamenco
* [#2433](https://github.com/nextcloud/deck/pull/2433) Fix scrollable titles with Dyslexia font
* [#2434](https://github.com/nextcloud/deck/pull/2434) Move most destructive actions in drop down menus to the bottom @Nienzu
* [#2435](https://github.com/nextcloud/deck/pull/2435) Do not open the dialog automatically upon card creation, only upon click
* [#2437](https://github.com/nextcloud/deck/pull/2437) Only remove card padding for editable cards
* [#2440](https://github.com/nextcloud/deck/pull/2440) Move navigation toggle handling to @nextcloud/vue native one
* [#2463](https://github.com/nextcloud/deck/pull/2463) Changed triple dots to ellipsis @rakekniven
* [#2500](https://github.com/nextcloud/deck/pull/2500) Move details and description to dedicated component
* [#2517](https://github.com/nextcloud/deck/pull/2517) Filter out duplicate cards in overview
* [#2502](https://github.com/nextcloud/deck/pull/2502) Assignment code refactoring
* [#2519](https://github.com/nextcloud/deck/pull/2519) Fix invisibility bug on modal component @wrox
* [#2520](https://github.com/nextcloud/deck/pull/2520) Add placeholder for the description input
* [#2521](https://github.com/nextcloud/deck/pull/2521) Add migration step to make table layout consistent
* [#2524](https://github.com/nextcloud/deck/pull/2524) Only try to extract first part of the explode result
* [#2531](https://github.com/nextcloud/deck/pull/2531) Add proper type to boolean parameter
* [#2532](https://github.com/nextcloud/deck/pull/2532) Fix handling of notifications if a board does no longer exist
* [#2536](https://github.com/nextcloud/deck/pull/2536) Only set flex layout on the active tab
* [#2538](https://github.com/nextcloud/deck/pull/2538) Do not reset filter when staying on the same board
* [#2539](https://github.com/nextcloud/deck/pull/2539) Apply proper checks for menu items
* [#2540](https://github.com/nextcloud/deck/pull/2540) Only build one main bundle
* [#2562](https://github.com/nextcloud/deck/pull/2562) Only try to extract first part of the explode result (Part 2)
## 1.1.0 - 2020-10-03
### Features
* [#2115](https://github.com/nextcloud/deck/pull/2115) Dashboard widget for Nextcloud 20
* [#1545](https://github.com/nextcloud/deck/pull/1545) Show cards in calendar/tasks app and make them available though CalDAV
* [#2200](https://github.com/nextcloud/deck/pull/2200) Unified search implementation for Nextcloud 20
* [#1934](https://github.com/nextcloud/deck/pull/1934) Upcoming cards overview @jakobroehrl
* [#2047](https://github.com/nextcloud/deck/pull/2047) Show card details in modal @jakobroehrl
* [#1853](https://github.com/nextcloud/deck/pull/1853) Archive all cards from stack @jakobroehrl
* [#1865](https://github.com/nextcloud/deck/pull/1865) Add stack button on empty board @jakobroehrl
* [#1926](https://github.com/nextcloud/deck/pull/1926) New filter: unassigned cards @jakobroehrl
### Bugfixes
* [#2035](https://github.com/nextcloud/deck/pull/2035) Attach files in description @jakobroehrl
* [#2123](https://github.com/nextcloud/deck/pull/2123) Fix control tooltip @jakobroehrl
* [#2144](https://github.com/nextcloud/deck/pull/2144) Fix nextcloud if install with dev dependencies @matchish
* [#2158](https://github.com/nextcloud/deck/pull/2158) Fix description in dark mode
* [#2188](https://github.com/nextcloud/deck/pull/2188) CardBadges: Count checkboxes started with "+ [ ]" @joreiff
* [#2206](https://github.com/nextcloud/deck/pull/2206) Fix read-only sidebar (fixes #2033)
* [#2208](https://github.com/nextcloud/deck/pull/2208) Fix design, dark mode and keyboard navigation of the board list
* [#2210](https://github.com/nextcloud/deck/pull/2210) Fix an incorrect/misleading message in lib/Service/BoardService.php @jordanbancino
* [#2243](https://github.com/nextcloud/deck/pull/2243) Various smaller styling fixes
* [#2244](https://github.com/nextcloud/deck/pull/2244) Toggle filter on clicking card labels
* [#2117](https://github.com/nextcloud/deck/pull/2117) Activity fixes
* [#2255](https://github.com/nextcloud/deck/pull/2255) Use unified search events to apply on board filtering
* [#2271](https://github.com/nextcloud/deck/pull/2271) Sort tags in filter @jakobroehrl
* [#2318](https://github.com/nextcloud/deck/pull/2318) Card title: prevent space and no text @jakobroehrl
* [#2319](https://github.com/nextcloud/deck/pull/2319) Move style loading to BeforeTemplateRenderedEvent
* [#2320](https://github.com/nextcloud/deck/pull/2320) Consistent naming @jakobroehrl
* [#2252](https://github.com/nextcloud/deck/pull/2252) Fix double slash in the deck activity links @baraksoa
* [#2270](https://github.com/nextcloud/deck/pull/2270) Fix empty content view to align with other widgets
* [#2275](https://github.com/nextcloud/deck/pull/2275) Wait for services to be registered before performing further setup that requires services
* [#2278](https://github.com/nextcloud/deck/pull/2278) Fix wrong SQL queries @Chartman123
* [#2279](https://github.com/nextcloud/deck/pull/2279) L10n:add translation to card placeholder @mjanssens
* [#2282](https://github.com/nextcloud/deck/pull/2282) Duedate picker localization
* [#2283](https://github.com/nextcloud/deck/pull/2283) Do not handle exceptions from page controller in the ExceptionMiddleware
* [#2298](https://github.com/nextcloud/deck/pull/2298) Use absolute URLs for the search @nickvergessen
## 1.0.5 - 2020-07-15
### Fixed
* [#2116](https://github.com/nextcloud/deck/pull/2116) Fix navigation layout issues @juliushaertl
* [#2118](https://github.com/nextcloud/deck/pull/2118) Use proper parameter when handling attachments @juliushaertl
## 1.0.4 - 2020-06-26
### Fixed
* [#2062](https://github.com/nextcloud/deck/pull/2062) Fix saving card description after toggling checkboxes @juliushaertl
* [#2065](https://github.com/nextcloud/deck/pull/2065) Adding CSS rule for Markdown Blockquotes @reox
* [#2059](https://github.com/nextcloud/deck/pull/2059) Fix fetching attachments on card change @juliushaertl
* [#2060](https://github.com/nextcloud/deck/pull/2060) Use mixing for relative date in card sidebar @juliushaertl
## 1.0.3 - 2020-06-19
### Fixed
* [#2019](https://github.com/nextcloud/deck/pull/2019) Remove old global css rule @juliushaertl
* [#2020](https://github.com/nextcloud/deck/pull/2020) Fix navigation issue with leftover nodes @juliushaertl
* [#2021](https://github.com/nextcloud/deck/pull/2021) Fix description issues @juliushaertl
* [#2022](https://github.com/nextcloud/deck/pull/2022) Fix replyto issues with the comments API @juliushaertl
* [#2027](https://github.com/nextcloud/deck/pull/2027) Allow to unassign current user from card @juliushaertl
* [#2029](https://github.com/nextcloud/deck/pull/2029) Fix wording : stack -> list @cloud2018
* [#2032](https://github.com/nextcloud/deck/pull/2032) Force order by id as second sorting key @juliushaertl
* [#2045](https://github.com/nextcloud/deck/pull/2045) Improve label styling @juliushaertl
* [#2010](https://github.com/nextcloud/deck/pull/2010) User documentation fixes @Nyco
* [#1998](https://github.com/nextcloud/deck/pull/1998) Add Checklist explaination to the doc @4rnoP
## 1.0.2 - 2020-06-03
### Fixed
* [#1774](https://github.com/nextcloud/deck/pull/1774) Remove deprecated global API calls
* [#1918](https://github.com/nextcloud/deck/pull/1918) Save compact mode on localstorage @jakobroehrl
* [#1919](https://github.com/nextcloud/deck/pull/1919) Show sidebar after card creation @jakobroehrl
* [#1924](https://github.com/nextcloud/deck/pull/1924) Boards ordered in main page @jakobroehrl
* [#1925](https://github.com/nextcloud/deck/pull/1925) Fix generated fronted urls
* [#1944](https://github.com/nextcloud/deck/pull/1944) Move navigation to @nextcloud/vue components
* [#1945](https://github.com/nextcloud/deck/pull/1945) Fix datetime picker
* [#1946](https://github.com/nextcloud/deck/pull/1946) Fix translations
* [#1976](https://github.com/nextcloud/deck/pull/1976) Delete boards that users own once they are deleted
* [#1977](https://github.com/nextcloud/deck/pull/1977) Redirect from previously used routes to the current ones
## 1.0.1 - 2020-05-15
### Fixed
* Removes debug filter output
* Labels are now sorted
* Stack title doesn't break up
* Fix move card modal
* Sort boards in navigation
* Fixes the attachment modal
* Handle deleted boards better
* User can only clone a board on canManage permissions
* Fix modal imports
* Show menu in compact mode
* Added a filter reset button
* Add hover effect to board list
* New filter icon
* Improve hovering response in board
* Enable linkify in description renderer @icewind1991
* Enhance board selector
* Fix issue if card description might be null
* Revert markdown styles from old frontend
* Do not scroll cards into view
* Fix reodering performance
## 1.0.0 - 2020-05-06
### Added
- Completly rewritten frontend
- Better maintainability
- Various small fixes
- Unified user interface with Nextcloud
- Separate comment and activity timelines
- Add ability to reply to comments #1537
- Filter cards on board #1507 @jakobroehrl
- Add cards to projects #1294 @jakobroehrl
- Move cards to other boards #1242 @jakobroehrl
- Clone boards with existing stacks and labels #1221 @jakobroehrl
- Upload multiple files at once and in parallel
A huge thangs goes to our awesome community that put enourmous effort into the frontend migration:
Special thanks for contributing huge parts of the Vue.js migration:
@jakobroehrl @weeman1337 @nicolad
Testers/reporters:
@cloud2018 @putt1ck @bpcurse
Android app team for helping to improve our REST API:
@desperateCoder @stefan-niedermann
## 0.8.0 - 2020-01-16
### Added
- Case insensitive search (@matchish)
### Fixed
- Fix reversed permissions for reordering stacks (@JLueke)
- Fix reversed visibility of 'add stack' field (@JLueke)
- Fix occ export command
- Fix error causing cron execution to fail
- Fix activity entry on moving cards
- Proper wording in activity timeline (@a11exandru)
## 0.7.0 - 2019-08-20
### Added
- Make deck compatible to Nextcloud 17
- Allow to set the description when creating cards though the REST API
## 0.6.6 - 2019-08-01
### Fixed
- Bump security related dependencies
## 0.6.5 - 2019-07-28
### Fixed
- Fix attachment upload/delete failures
- Bump dependencies
## 0.6.4 - 2019-06-30
### Fixed
- Restore stable15 compatibility
## 0.6.3 - 2019-06-30
### Fixed
- Fix issues with comments and activity stream
- Fix setting archived state through API
- Fix type of acl in API responses
- Fix type mismatch with fulltext search
## 0.6.2 - 2019-05-15
### Fixed
- Fix group limit for nonexisting groups
- Only map circle ACLs if the app is enabled
- Fix updating sharing permissions
- Add app version to capabilities
## 0.6.1 - 2019-04-27
### Fixed
- Fix issue with boards not being shown after update
- Fix board selection in projects view outside of deck
- Remove collections text from sidebar
- Remove leftover use statement
## 0.6.0 - 2019-04-23
### Added
- Share boards with circles
- Integration with collections in Nextcloud 16
- Support for full text search
- Nextcloud 16 compatibility
### Fixed
- Fix duplicate call to delete
- Prevent duplicate tag names @jakobroehrl
- Prevent loading details when editing the card title @jakobroehrl
- Hide sidebar after card deletion @jakobroehrl
- Update labels after change in the UI @jakobroehrl
- Allow limiting the app to groups again
- Various REST API enhancements and fixes
- Fix some issues with comments/activites
## 0.5.2 - 2018-12-20
### Fixed
- Mark notification as read if a card with duedate gets archived
- Use proper timezone and locale format for due date activities
- Various translation fixes and updates
- Check group limit properly
- Fix comment activities on Nextcloud 15
- Fix issues with Edge
- API: Fix numeric types that were returned as strings
- API: Fix If-Modified-Since header parsing
## 0.5.1 - 2018-12-05
### Added
- Separate settings for description changes in activity
- Less verbose description change activities
- Use server settings to restrict sharing to groups
- Add setting to exclude groups from creating their own boards
### Fixed
- Fix issue when using a separate table prefix @bpcurse
- Fix invalid activity parameters being published
- Wording fixes @cloud2018
- Improve loading performance by removing unused activity preloading
- Fix timestamp issues in deleted items tab
- Remember show state of the board navigation @weeman1337
- Add optional classes for custom styling @tinko92
- Fix missing details on activity emails
- Fix unrelated comments in board activity list
- Fix search not working properly
- Trigger comment notification on update only
## 0.5.0 - 2018-11-15
### Added
- Activity stream for board and cards
- Comments on cards
- Use users locale format on date picker
- Compact display mode
- Card title inline editing
- REST API
- Empty content view for board lists
- Undo for card and stack deletion
- Show tag name on board
- Notify users about card assignments
- Add shortcut to assign a card to yourself
- Improved view for printing
- Support for Nextcloud 15
### Fixed
- Accesibility improvements
- Don't allow empty card titles
- Improved checkbox handling in markdown
## 0.4.0 - 2018-07-11
### Added
- Attach files to cards
- Embed attachments into the card description
- Color picker to use any color value for board and labels
- Support for checkboxes inside the description
- occ command to export user data as JSON
### Fixed
- Improve frontend data management
- Fix bug the user list being empty on some occasions
## 0.3.0 - 2018-01-12

View File

@@ -14,30 +14,64 @@ cert_dir=$(HOME)/.nextcloud/certificates
default: build
clean-build:
rm -rf $(build_dir)
clean-dist:
rm -rf node_modules/
rm -rf js/node_modules
rm -rf js/vendor
install-deps: install-deps-js
composer install
install-deps:
cd js && npm install --deps
cd js && ./node_modules/.bin/bower install
install-deps-nodev: install-deps-js
composer install --no-dev
build: build-js
install-deps-js:
npm ci
build: clean-dist install-deps build-js
release: clean-dist install-deps-nodev build-js
build-js: install-deps-js
npm run build
build-js-dev: install-deps
npm run dev
build-js: install-deps
cd js && ./node_modules/.bin/grunt build
watch:
npm run watch
cd js && ./node_modules/.bin/grunt watch
# appstore: clean install-deps
appstore: clean-build build
rm -rf $(appstore_build_directory)
mkdir -p $(appstore_build_directory)
tar cvzf $(appstore_package_name).tar.gz \
--exclude="../$(app_name)/build" \
--exclude="../$(app_name)/tests" \
--exclude="../$(app_name)/Makefile" \
--exclude="../$(app_name)/*.log" \
--exclude="../$(app_name)/phpunit*xml" \
--exclude="../$(app_name)/composer.*" \
--exclude="../$(app_name)/js/node_modules" \
--exclude="../$(app_name)/js/tests" \
--exclude="../$(app_name)/js/test" \
--exclude="../$(app_name)/js/*.log" \
--exclude="../$(app_name)/js/package-lock.json" \
--exclude="../$(app_name)/js/package.json" \
--exclude="../$(app_name)/js/bower.json" \
--exclude="../$(app_name)/js/karma.*" \
--exclude="../$(app_name)/js/protractor.*" \
--exclude="../$(app_name)/package.json" \
--exclude="../$(app_name)/bower.json" \
--exclude="../$(app_name)/karma.*" \
--exclude="../$(app_name)/protractor\.*" \
--exclude="../$(app_name)/.*" \
--exclude="../$(app_name)/*.lock" \
--exclude="../$(app_name)/run-eslint.sh" \
--exclude="../$(app_name)/js/.*" \
--exclude="../$(app_name)/vendor" \
--exclude-vcs \
../$(app_name)
@if [ -f $(cert_dir)/$(app_name).key ]; then \
echo "Signing package…"; \
openssl dgst -sha512 -sign $(cert_dir)/$(app_name).key $(build_dir)/$(app_name).tar.gz | openssl base64; \
fi
echo $(appstore_package_name).tar.gz
test: test-unit test-integration
@@ -46,7 +80,7 @@ test-unit:
ifeq (, $(shell which phpunit 2> /dev/null))
@echo "No phpunit command available, downloading a copy from the web"
mkdir -p $(build_tools_directory)
curl -sSL https://phar.phpunit.de/phpunit-8.2.phar -o $(build_tools_directory)/phpunit.phar
curl -sSL https://phar.phpunit.de/phpunit-5.7.phar -o $(build_tools_directory)/phpunit.phar
php $(build_tools_directory)/phpunit.phar -c tests/phpunit.xml --coverage-clover build/php-unit.coverage.xml
php $(build_tools_directory)/phpunit.phar -c tests/phpunit.integration.xml --coverage-clover build/php-integration.coverage.xml
else
@@ -58,4 +92,5 @@ test-integration:
cd tests/integration && ./run.sh
test-js: install-deps
npm run test
cd js && run test

View File

@@ -1,29 +1,30 @@
# Deck
[![Build Status](https://travis-ci.org/nextcloud/deck.svg?branch=master)](https://travis-ci.org/nextcloud/deck) [![CodeCov](https://codecov.io/github/nextcloud/deck/coverage.svg?branch=master)](https://codecov.io/github/nextcloud/deck) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e403f723f42a4abd93b2cfe36cbd7eee)](https://www.codacy.com/app/juliushaertl/deck?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=nextcloud/deck&amp;utm_campaign=Badge_Grade) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nextcloud/deck/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/nextcloud/deck/?branch=master) [![#nextcloud-deck](https://img.shields.io/badge/IRC-%23nextcloud--deck%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-deck)
[![Build Status](https://travis-ci.org/nextcloud/deck.svg?branch=master)](https://travis-ci.org/nextcloud/deck) [![CodeCov](https://codecov.io/github/nextcloud/deck/coverage.svg?branch=master)](https://codecov.io/github/nextcloud/deck) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/nextcloud/deck/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/nextcloud/deck/?branch=master) [![Dependency Status](https://www.versioneye.com/user/projects/58ad558f4ca76f004ed475b3/badge.svg?style=flat)](https://www.versioneye.com/user/projects/58ad558f4ca76f004ed475b3) [![#nextcloud-deck](https://img.shields.io/badge/IRC-%23nextcloud--deck%20on%20freenode-blue.svg)](https://webchat.freenode.net/?channels=nextcloud-deck)
Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.
- Add your tasks to cards and put them in order
- Write down additional notes in markdown
- Assign labels for even better organization
- Share with your team, friends or family
- Integrates with the [Circles](https://github.com/nextcloud/circles) app!
- Attach files and embed them in your markdown description
- Discuss with your team using comments
- Keep track of changes in the activity stream
- Get your project organized
- :inbox_tray: Add your tasks to cards and put them in order
- :page_facing_up: Write down additional notes in markdown
- :bookmark: Assign labels for even better organization
- :busts_in_silhouette: Share with your team, friends or family
- :rocket: Get your project organized
### Mobile apps
- The [Nextcloud Deck app for Android](https://github.com/stefan-niedermann/nextcloud-deck) is available in the [Google Play Store](https://play.google.com/store/apps/details?id=it.niedermann.nextcloud.deck.play)
![Deck - Manage cards on your board](https://download.bitgrid.net/nextcloud/deck/screenshots/Deck_Board.png)
![Deck - Manage cards on your board](http://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-2.png)
### Planned features
- :file_folder: Attach files directly from your Nextcloud
- :earth_africa: Share boards with the public
- :calendar: Integration with Nextcloud calendar and other apps
- :speech_balloon: Comments integration
- :exclamation: Checkout the project milestones for more ...
## Installation/Update
This app is supposed to work on the two latest Nextcloud versions.
This app is supposed to work on Nextcloud version 11 or later.
### Install latest release
@@ -37,14 +38,14 @@ If you want to run the latest development version from git source, you need to c
git clone https://github.com/nextcloud/deck.git
cd deck
make install-deps
make build
make
```
Please make sure you have installed the following dependencies: `make, which, tar, npm, curl, composer`
Please make sure you have installed the following dependencies: `make, which, tar, npm, curl`
### Install the nightly builds
Instead of setting everything up manually, you can just [download the nightly build](https://github.com/nextcloud/deck/releases/tag/nightly) instead. These builds are updated every 24 hours, and are pre-configured with all the needed dependencies.
Instead of setting everything up manually, you can just [download the nightly builds](https://download.bitgrid.net/nextcloud/deck/nightly/) instead. These builds are updated every 24 hours, and are pre-configured with all the needed dependencies.
## Developing
@@ -54,43 +55,21 @@ Nothing to prepare, just dig into the code.
### JavaScript
Deck requires running a `make build-js` to install npm dependencies and build the JavaScript code using webpack. While developing you can also use `make watch` to rebuild everytime the code changes.
#### Hot reloading
Enable debug mode in your config.php `'debug' => true,`
Without SSL:
```
npx webpack-dev-server --config webpack.hot.js \
--public localhost:3000 \
--output-public-path 'http://localhost:3000/js/'
```
With SSL:
```
npx webpack-dev-server --config webpack.dev.js --https \
--cert ~/repos/nextcloud/nc-dev/data/ssl/nextcloud.local.crt \
--key ~/repos/nextcloud/nc-dev/data/ssl/nextcloud.local.key \
--public nextcloud.local:3000 \
--output-public-path 'https://nextcloud.local:3000/js/'
```
When `'debug'=>true` is set in your config.php files will get loaded automatically. Otherwise you need to ensure that `public/app.js` is generated by running `make` or `make watch` to regenerate it on every change.
Make sure you have installed the dependencies with ```make install-deps```.
### Running tests
You can use the provided Makefile to run all tests by using:
make test
### Documentation
The documentation for our REST API can be found at https://deck.readthedocs.io/en/latest/API/
## Contribution Guidelines
Please read the [Code of Conduct](https://nextcloud.com/community/code-of-conduct/). This document offers some guidance to ensure Nextcloud participants can cooperate effectively in a positive and inspiring atmosphere, and to explain how together we can strengthen and support each other.
For more information please review the [guidelines for contributing](https://github.com/nextcloud/server/blob/master/.github/CONTRIBUTING.md) to this repository.
For more information please review the [guidelines for contributing](https://github.com/nextcloud/server/blob/master/CONTRIBUTING.md) to this repository.
### Apply a license

View File

@@ -1,29 +0,0 @@
# Security Policy
## Supported Versions
| Version | Nextcloud version | Supported |
| ------- | ----------------- | ------------------ |
| 1.0.x | 18, 19 | :white_check_mark: |
| 0.8.x | 17 | :white_check_mark: |
| <0.7.x | - | :x: |
## Reporting a Vulnerability
Security is very important to us. If you have discovered a security issue with Nextcloud,
please read our responsible disclosure guidelines and contact us at [hackerone.com/nextcloud](https://hackerone.com/nextcloud).
Your report should include:
- Product version
- A vulnerability description
- Reproduction steps
A member of the security team will confirm the vulnerability, determine its impact, and develop a fix.
The fix will be applied to the master branch, tested, and packaged in the next security release.
The vulnerability will be publicly announced after the release. Finally, your name will be added
to the [hall of fame](https://hackerone.com/nextcloud/thanks) as a thank you from the entire Nextcloud community. Note our
[threat model](https://nextcloud.com/security/threat-model) to know what is expected behavior.
Please visit https://nextcloud.com/security/ for further information about security.

2
_config.yml Normal file
View File

@@ -0,0 +1,2 @@
theme: jekyll-theme-cayman
site: https://deck-app.com

View File

@@ -1,11 +1,8 @@
/*
<?php
/**
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Artem Anufrij <artem.anufrij@live.de>
* @author Marin Treselj <marin@pixelipo.com>
* @author Oskar Kurz <oskar.kurz@gmail.com>
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
*
* @license GNU AGPL version 3 or any later version
*
@@ -24,5 +21,6 @@
*
*/
@import 'icons';
@import 'print';
$app = new \OCA\Deck\AppInfo\Application();
$app->registerNavigationEntry();
$app->registerNotifications();

View File

@@ -5,25 +5,27 @@
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
namespace OCA\Deck\AppInfo;
use OCP\AppFramework\App;
/**
* Additional autoloader registration, e.g. registering composer autoloaders
*/
require_once __DIR__ . '/../vendor/autoload.php';
// require_once __DIR__ . '/../vendor/autoload.php';

426
appinfo/database.xml Normal file
View File

@@ -0,0 +1,426 @@
<?xml version="1.0" encoding="UTF-8" ?>
<database>
<name>*dbname*</name>
<create>true</create>
<overwrite>false</overwrite>
<charset>utf8</charset>
<table>
<name>*dbprefix*deck_boards</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>owner</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>color</name>
<type>text</type>
<length>6</length>
<notnull>false</notnull>
</field>
<field>
<name>archived</name>
<type>boolean</type>
<default>false</default>
</field>
<field>
<name>deleted_at</name>
<type>integer</type>
<default>0</default>
<length>8</length>
<notnull>false</notnull>
<unsigned>true</unsigned>
</field>
</declaration>
</table>
<table>
<name>*dbprefix*deck_stacks</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>board_id</name>
<type>integer</type>
<length>8</length>
<notnull>true</notnull>
</field>
<field>
<name>order</name>
<type>integer</type>
<length>8</length>
<notnull>false</notnull>
</field>
<index>
<name>deck_stacks_board_id_index</name>
<field>
<name>board_id</name>
</field>
</index>
<index>
<name>deck_stacks_order_index</name>
<field>
<name>order</name>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*deck_cards</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>title</name>
<type>text</type>
<length>100</length>
<notnull>true</notnull>
</field>
<field>
<name>description</name>
<type>clob</type>
<notnull>false</notnull>
</field>
<field>
<name>stack_id</name>
<type>integer</type>
<length>8</length>
<notnull>true</notnull>
</field>
<field>
<name>type</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
<default>plain</default>
</field>
<field>
<name>last_modified</name>
<type>integer</type>
<default></default>
<notnull>false</notnull>
<unsigned>true</unsigned>
</field>
<field>
<name>created_at</name>
<type>integer</type>
<default></default>
<notnull>false</notnull>
<unsigned>true</unsigned>
</field>
<field>
<name>owner</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>order</name>
<type>integer</type>
<length>8</length>
<notnull>false</notnull>
</field>
<field>
<name>archived</name>
<type>boolean</type>
<default>false</default>
</field>
<field>
<name>duedate</name>
<type>timestamp</type>
<default>0</default>
</field>
<field>
<name>notified</name>
<type>boolean</type>
<default>false</default>
</field>
<index>
<name>deck_cards_stack_id_index</name>
<field>
<name>stack_id</name>
</field>
</index>
<index>
<name>deck_cards_order_index</name>
<field>
<name>order</name>
</field>
</index>
<index>
<name>deck_cards_archived_index</name>
<field>
<name>archived</name>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*deck_attachment</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>title</name>
<type>text</type>
<notnull>true</notnull>
<length>100</length>
</field>
<field>
<name>card_id</name>
<type>integer</type>
<length>8</length>
<notnull>true</notnull>
</field>
<field>
<name>type</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>data</name>
<type>clob</type>
</field>
<field>
<name>last_modified</name>
<type>integer</type>
<default></default>
<length>8</length>
<notnull>false</notnull>
<unsigned>true</unsigned>
</field>
<field>
<name>created_at</name>
<type>integer</type>
<default></default>
<length>8</length>
<notnull>false</notnull>
<unsigned>true</unsigned>
</field>
</declaration>
</table>
<table>
<name>*dbprefix*deck_labels</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>title</name>
<type>text</type>
<notnull>false</notnull>
<length>100</length>
</field>
<field>
<name>color</name>
<type>text</type>
<length>6</length>
<notnull>false</notnull>
</field>
<field>
<name>board_id</name>
<type>integer</type>
<notnull>true</notnull>
<length>8</length>
</field>
<index>
<name>deck_labels_board_id_index</name>
<field>
<name>board_id</name>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*deck_assigned_labels</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>label_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>card_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
</field>
<index>
<name>deck_assigned_labels_idx_i</name>
<field>
<name>label_id</name>
</field>
</index>
<index>
<name>deck_assigned_labels_idx_c</name>
<field>
<name>card_id</name>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*deck_assigned_users</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>participant</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>card_id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<length>4</length>
</field>
<index>
<name>deck_assigned_users_idx_p</name>
<field>
<name>participant</name>
</field>
</index>
<index>
<name>deck_assigned_users_idx_c</name>
<field>
<name>card_id</name>
</field>
</index>
</declaration>
</table>
<table>
<name>*dbprefix*deck_board_acl</name>
<declaration>
<field>
<name>id</name>
<type>integer</type>
<default>0</default>
<notnull>true</notnull>
<autoincrement>1</autoincrement>
<length>4</length>
</field>
<field>
<name>board_id</name>
<type>integer</type>
<notnull>true</notnull>
<length>8</length>
</field>
<field>
<name>type</name>
<type>integer</type>
<notnull>true</notnull>
<length>4</length>
</field>
<field>
<name>participant</name>
<type>text</type>
<notnull>true</notnull>
<length>64</length>
</field>
<field>
<name>permission_edit</name>
<type>boolean</type>
<default>false</default>
</field>
<field>
<name>permission_share</name>
<type>boolean</type>
<default>false</default>
</field>
<field>
<name>permission_manage</name>
<type>boolean</type>
<default>false</default>
</field>
<index>
<name>deck_board_acl_uq_i</name>
<unique>true</unique>
<field>
<name>board_id</name>
<sorting>ascending</sorting>
</field>
<field>
<name>type</name>
<sorting>ascending</sorting>
</field>
<field>
<name>participant</name>
<sorting>ascending</sorting>
</field>
</index>
<index>
<name>deck_board_acl_idx_i</name>
<field>
<name>board_id</name>
</field>
</index>
</declaration>
</table>
</database>

View File

@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>deck</id>
<name>Deck</name>
<summary>Personal planning and team project organization</summary>
<summary>A kanban style project and personal management tool for Nextcloud</summary>
<description>Deck is a kanban style organization tool aimed at personal planning and project organization for teams integrated with Nextcloud.
@@ -10,68 +11,30 @@
- 📄 Write down additional notes in markdown
- 🔖 Assign labels for even better organization
- 👥 Share with your team, friends or family
- 📎 Attach files and embed them in your markdown description
- 💬 Discuss with your team using comments
- ⚡ Keep track of changes in the activity stream
- 🚀 Get your project organized
</description>
<version>1.4.7</version>
<version>0.3.1-rc1</version>
<licence>agpl</licence>
<author>Julius Härtl</author>
<namespace>Deck</namespace>
<types>
<dav/>
</types>
<category>organization</category>
<category>office</category>
<website>https://github.com/nextcloud/deck</website>
<bugs>https://github.com/nextcloud/deck/issues</bugs>
<repository type="git">https://github.com/nextcloud/deck.git</repository>
<screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-1.png</screenshot>
<screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/1.0/Deck-2.png</screenshot>
<screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/Deck_Board.png</screenshot>
<screenshot>https://download.bitgrid.net/nextcloud/deck/screenshots/Deck_Details.png</screenshot>
<dependencies>
<php min-version="7.3"/>
<database min-version="9.4">pgsql</database>
<database>sqlite</database>
<database min-version="5.5">mysql</database>
<nextcloud min-version="21" max-version="21"/>
<nextcloud min-version="12" max-version="13" />
</dependencies>
<background-jobs>
<job>OCA\Deck\Cron\DeleteCron</job>
<job>OCA\Deck\Cron\ScheduledNotifications</job>
<job>OCA\Deck\Cron\CardDescriptionActivity</job>
</background-jobs>
<commands>
<command>OCA\Deck\Command\UserExport</command>
</commands>
<activity>
<settings>
<setting>OCA\Deck\Activity\Setting</setting>
<setting>OCA\Deck\Activity\SettingComment</setting>
<setting>OCA\Deck\Activity\DescriptionSetting</setting>
</settings>
<filters>
<filter>OCA\Deck\Activity\Filter</filter>
</filters>
<providers>
<provider>OCA\Deck\Activity\DeckProvider</provider>
</providers>
</activity>
<fulltextsearch>
<provider min-version="16">OCA\Deck\Provider\DeckProvider</provider>
</fulltextsearch>
<navigations>
<navigation>
<name>Deck</name>
<route>deck.page.index</route>
<icon>deck.svg</icon>
<order>10</order>
</navigation>
</navigations>
<sabre>
<calendar-plugins>
<plugin>OCA\Deck\DAV\CalendarPlugin</plugin>
</calendar-plugins>
</sabre>
<repair-steps>
<post-migration>
<step>OCA\Deck\Migration\UnknownUsers</step>
</post-migration>
</repair-steps>
</info>

View File

@@ -3,23 +3,22 @@
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
*
* @license GNU AGPL version 3 or any later version
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
return [
@@ -35,9 +34,8 @@ return [
['name' => 'board#deleteUndo', 'url' => '/boards/{boardId}/deleteUndo', 'verb' => 'POST'],
['name' => 'board#getUserPermissions', 'url' => '/boards/{boardId}/permissions', 'verb' => 'GET'],
['name' => 'board#addAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'POST'],
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
['name' => 'board#updateAcl', 'url' => '/boards/{boardId}/acl', 'verb' => 'PUT'],
['name' => 'board#deleteAcl', 'url' => '/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
['name' => 'board#clone', 'url' => '/boards/{boardId}/clone', 'verb' => 'POST'],
// stacks
['name' => 'stack#index', 'url' => '/stacks/{boardId}', 'verb' => 'GET'],
@@ -45,7 +43,6 @@ return [
['name' => 'stack#update', 'url' => '/stacks/{stackId}', 'verb' => 'PUT'],
['name' => 'stack#reorder', 'url' => '/stacks/{stackId}/reorder', 'verb' => 'PUT'],
['name' => 'stack#delete', 'url' => '/stacks/{stackId}', 'verb' => 'DELETE'],
['name' => 'stack#deleted', 'url' => '/{boardId}/stacks/deleted', 'verb' => 'GET'],
['name' => 'stack#archived', 'url' => '/stacks/{boardId}/archived', 'verb' => 'GET'],
// cards
@@ -53,7 +50,6 @@ return [
['name' => 'card#create', 'url' => '/cards', 'verb' => 'POST'],
['name' => 'card#update', 'url' => '/cards/{cardId}', 'verb' => 'PUT'],
['name' => 'card#delete', 'url' => '/cards/{cardId}', 'verb' => 'DELETE'],
['name' => 'card#deleted', 'url' => '/{boardId}/cards/deleted', 'verb' => 'GET'],
['name' => 'card#rename', 'url' => '/cards/{cardId}/rename', 'verb' => 'PUT'],
['name' => 'card#reorder', 'url' => '/cards/{cardId}/reorder', 'verb' => 'PUT'],
['name' => 'card#archive', 'url' => '/cards/{cardId}/archive', 'verb' => 'PUT'],
@@ -61,87 +57,12 @@ return [
['name' => 'card#assignLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'POST'],
['name' => 'card#removeLabel', 'url' => '/cards/{cardId}/label/{labelId}', 'verb' => 'DELETE'],
['name' => 'card#assignUser', 'url' => '/cards/{cardId}/assign', 'verb' => 'POST'],
['name' => 'card#unassignUser', 'url' => '/cards/{cardId}/unassign', 'verb' => 'PUT'],
// attachments
['name' => 'attachment#getAll', 'url' => '/cards/{cardId}/attachments', 'verb' => 'GET'],
['name' => 'attachment#create', 'url' => '/cards/{cardId}/attachment', 'verb' => 'POST'],
['name' => 'attachment#display', 'url' => '/cards/{cardId}/attachment/{attachmentId}', 'verb' => 'GET'],
['name' => 'attachment#update', 'url' => '/cards/{cardId}/attachment/{attachmentId}', 'verb' => 'PUT'],
// also allow to use POST for updates so we can properly access files when using application/x-www-form-urlencoded
['name' => 'attachment#update', 'url' => '/cards/{cardId}/attachment/{attachmentId}', 'verb' => 'POST'],
['name' => 'attachment#delete', 'url' => '/cards/{cardId}/attachment/{attachmentId}', 'verb' => 'DELETE'],
['name' => 'attachment#restore', 'url' => '/cards/{cardId}/attachment/{attachmentId}/restore', 'verb' => 'GET'],
['name' => 'card#unassignUser', 'url' => '/cards/{cardId}/assign/{userId}', 'verb' => 'DELETE'],
// labels
['name' => 'label#create', 'url' => '/labels', 'verb' => 'POST'],
['name' => 'label#update', 'url' => '/labels/{labelId}', 'verb' => 'PUT'],
['name' => 'label#delete', 'url' => '/labels/{labelId}', 'verb' => 'DELETE'],
// api
['name' => 'board_api#index', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'GET'],
['name' => 'board_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'GET'],
['name' => 'board_api#create', 'url' => '/api/v{apiVersion}/boards', 'verb' => 'POST'],
['name' => 'board_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'DELETE'],
['name' => 'board_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}', 'verb' => 'PUT'],
['name' => 'board_api#undo_delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/undo_delete', 'verb' => 'POST'],
['name' => 'board_api#addAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl', 'verb' => 'POST'],
['name' => 'board_api#deleteAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl/{aclId}', 'verb' => 'DELETE'],
['name' => 'board_api#updateAcl', 'url' => '/api/v{apiVersion}/boards/{boardId}/acl/{aclId}', 'verb' => 'PUT'],
['name' => 'stack_api#index', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks', 'verb' => 'GET'],
['name' => 'stack_api#getArchived', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/archived', 'verb' => 'GET'],
['name' => 'stack_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}', 'verb' => 'GET'],
['name' => 'stack_api#create', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks', 'verb' => 'POST'],
['name' => 'stack_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}', 'verb' => 'PUT'],
['name' => 'stack_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}', 'verb' => 'DELETE'],
['name' => 'card_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}', 'verb' => 'GET'],
['name' => 'card_api#create', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards', 'verb' => 'POST'],
['name' => 'card_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}', 'verb' => 'PUT'],
['name' => 'card_api#assignLabel', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/assignLabel', 'verb' => 'PUT'],
['name' => 'card_api#removeLabel', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/removeLabel', 'verb' => 'PUT'],
['name' => 'card_api#assignUser', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/assignUser', 'verb' => 'PUT'],
['name' => 'card_api#unassignUser', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/unassignUser', 'verb' => 'PUT'],
['name' => 'card_api#reorder', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/reorder', 'verb' => 'PUT'],
['name' => 'card_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}', 'verb' => 'DELETE'],
['name' => 'card_api#findAllWithDue', 'url' => '/api/v{apiVersion}/dashboard/due', 'verb' => 'GET'],
['name' => 'label_api#get', 'url' => '/api/v{apiVersion}/boards/{boardId}/labels/{labelId}', 'verb' => 'GET'],
['name' => 'label_api#create', 'url' => '/api/v{apiVersion}/boards/{boardId}/labels', 'verb' => 'POST'],
['name' => 'label_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}/labels/{labelId}', 'verb' => 'PUT'],
['name' => 'label_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/labels/{labelId}', 'verb' => 'DELETE'],
['name' => 'attachment_api#getAll', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments', 'verb' => 'GET', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api#display', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'GET', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api#create', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments', 'verb' => 'POST', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api#update', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'PUT', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api#restore', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{attachmentId}/restore', 'verb' => 'PUT', 'requirements' => ['apiVersion' => '1.0']],
['name' => 'attachment_api_v11#getAll', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments', 'verb' => 'GET', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'attachment_api_v11#display', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{type}/{attachmentId}', 'verb' => 'GET', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'attachment_api_v11#create', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments', 'verb' => 'POST', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'attachment_api_v11#update', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{type}/{attachmentId}', 'verb' => 'PUT', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'attachment_api_v11#delete', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{type}/{attachmentId}', 'verb' => 'DELETE', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'attachment_api_v11#restore', 'url' => '/api/v{apiVersion}/boards/{boardId}/stacks/{stackId}/cards/{cardId}/attachments/{type}/{attachmentId}/restore', 'verb' => 'PUT', 'requirements' => ['apiVersion' => '1.1']],
['name' => 'board_api#preflighted_cors', 'url' => '/api/v{apiVersion}/{path}','verb' => 'OPTIONS', 'requirements' => ['path' => '.+']],
],
'ocs' => [
['name' => 'Config#get', 'url' => '/api/v{apiVersion}/config', 'verb' => 'GET'],
['name' => 'Config#setValue', 'url' => '/api/v{apiVersion}/config/{key}', 'verb' => 'POST'],
['name' => 'comments_api#list', 'url' => '/api/v{apiVersion}/cards/{cardId}/comments', 'verb' => 'GET'],
['name' => 'comments_api#create', 'url' => '/api/v{apiVersion}/cards/{cardId}/comments', 'verb' => 'POST'],
['name' => 'comments_api#update', 'url' => '/api/v{apiVersion}/cards/{cardId}/comments/{commentId}', 'verb' => 'PUT'],
['name' => 'comments_api#delete', 'url' => '/api/v{apiVersion}/cards/{cardId}/comments/{commentId}', 'verb' => 'DELETE'],
['name' => 'overview_api#upcomingCards', 'url' => '/api/v{apiVersion}/overview/upcoming', 'verb' => 'GET'],
['name' => 'search#search', 'url' => '/api/v{apiVersion}/search', 'verb' => 'GET'],
]
];

View File

@@ -1,11 +0,0 @@
module.exports = {
plugins: ['@babel/plugin-syntax-dynamic-import'],
presets: [
[
'@babel/preset-env',
{
modules: false
}
]
]
}

View File

@@ -1,40 +1,16 @@
{
"name": "nextcloud/deck",
"type": "project",
"license": "AGPLv3",
"authors": [
{
"name": "Julius Härtl",
"email": "jus@bitgrid.net"
}
],
"require": {
"cogpowered/finediff": "0.3.*"
},
"require-dev": {
"roave/security-advisories": "dev-master",
"christophwurst/nextcloud": "^21@dev",
"phpunit/phpunit": "^8",
"nextcloud/coding-standard": "^0.5.0",
"symfony/event-dispatcher": "^4.0",
"vimeo/psalm": "^4.3",
"php-parallel-lint/php-parallel-lint": "^1.2"
},
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true
},
"scripts": {
"lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l",
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"psalm": "psalm",
"psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType",
"test": [
"@test:unit",
"@test:integration"
],
"test:unit": "phpunit -c tests/phpunit.xml",
"test:integration": "phpunit -c tests/phpunit.integration.xml && cd tests/integration && ./run.sh"
}
"name": "nextcloud/deck",
"type": "project",
"license": "AGPLv3",
"authors": [
{
"name": "Julius Härtl",
"email": "jus@bitgrid.net"
}
],
"require": {},
"require-dev": {
"christophwurst/nextcloud": "^12.0",
"jakub-onderka/php-parallel-lint": "^0.9.2"
}
}

4917
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,28 +0,0 @@
.activitymessage .visualdiff ins {
background-color: rgba(70, 186, 97, 0.2);
text-decoration: none;
}
.activitymessage .visualdiff del {
background-color: rgba(233, 50, 45, 0.2);
text-decoration: none;
}
.activitymessage .visualdiff {
overflow: scroll;
max-height: 200px;
}
.activityTabView .avatardiv-container {
display: inline-block;
bottom: -3px;
margin-left: 3px;
}
.activityTabView .avatar-name-wrapper {
font-weight: bold;
}
.activityTabView .activitysubject a {
font-weight: bold;
}

View File

@@ -1,7 +0,0 @@
.resource-type-deck img {
opacity: 0.4 !important;
}
.resource-type-deck:hover img {
opacity: 0.7 !important;
}

113
css/comp-appnav.scss Normal file
View File

@@ -0,0 +1,113 @@
/*
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
* @copyright Copyright (c) 2016, John Molakvoæ <skjnldsv@protonmail.com>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Hotfix for support <NC13 with new app sidebar
*/
#app-navigation {
.app-navigation-entry-menu.open {
ul li a {
background-position: 10px center;
padding: 0 10px 0 36px !important;
}
}
.app-navigation-entry-edit {
display: none;
}
.editing {
.app-navigation-entry-edit {
display: block;
position: absolute;
background: $color-main-background;
height: auto;
z-index: 250;
}
}
}
/**
* copied styles from core/css/styles.scss
* to have the same breadcrumb styling in NC12
*/
.breadcrumb {
display: inline-flex;
}
div.crumb {
display: inline-flex;
background-repeat: no-repeat;
background-position: right center;
height: 44px;
background-size: auto 24px;
flex: 0 0 auto;
order: 1;
padding-right: 7px;
&.crumbmenu {
order: 2;
position: relative;
a {
opacity: 0.5
}
}
&.hidden {
display: none;
~ .crumb {
order: 3;
}
}
> a,
> span {
position: relative;
padding: 12px;
opacity: 0.5;
top: 0 !important;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
flex: 0 0 auto;
&.icon-home {
// Hide home text
text-indent: -9999px;
}
}
> a[class^='icon-'] {
padding: 0;
width: 44px;
}
&:not(:first-child) a {
}
&:last-child {
font-weight: 600;
margin-right: 10px;
// Allow multiple span next to the main 'a'
a ~ span {
padding-left: 0;
}
}
&:hover, &:focus, a:focus, &:active {
> a,
> span {
opacity: .7;
}
}
}

View File

@@ -1 +0,0 @@
@include icon-black-white('deck', 'deck', 1);

View File

@@ -1,41 +1,42 @@
/**
* Custom icons
*/
@include icon-black-white('deck', 'deck', 1);
@include icon-black-white('archive', 'deck', 1);
@include icon-black-white('circles', 'deck', 1);
@include icon-black-white('clone', 'deck', 1);
@include icon-black-white('filter', 'deck', 1);
@include icon-black-white('filter_set', 'deck', 1);
@include icon-black-white('attach', 'deck', 1);
@include icon-black-white('reply', 'deck', 1);
@include icon-black-white('notifications-dark', 'deck', 1);
@include icon-black-white('description', 'deck', 1);
.icon-toggle-compact-collapsed {
@include icon-color('toggle-view-expand', 'deck', $color-black);
.icon-deck {
background-image: url('../img/deck-dark.svg');
}
.icon-toggle-compact-expanded {
@include icon-color('toggle-view-collapse', 'deck', $color-black);
}
.icon-activity {
@include icon-color('activity-dark', 'activity', $color-black);
}
.icon-comment--unread {
@include icon-color('comment', 'actions', $color-primary, 1, true);
.icon-group {
background-image: url('../../../settings/img/users.svg');
}
.avatardiv.circles {
background: var(--color-primary);
.icon-help {
background-image: url('../../../settings/img/help.svg');
}
.icon-circles {
opacity: 1;
background-size: 20px;
background-position: center center;
.icon-add-white {
background-image: url('../img/add-white.svg');
}
.icon-colorpicker {
background-image: url('../img/color_picker.svg');
.icon-archive {
background-image: url('../img/archive.svg');
}
.icon-archive-white {
background-image: url('../img/archive-white.svg');
}
.icon-details {
background-image: url('../img/details.svg');
}
.icon-details-white {
background-image: url('../img/details-white.svg');
}
.icon-home {
background-image: url('../../../core/img/places/home.svg');
}
.icon-badge {
background-image: url('../../../core/img/places/calendar-dark.svg');
}

View File

@@ -1,98 +0,0 @@
@media print {
/* hide stuff */
#body-user {
#header,
.app-navigation,
.app-sidebar,
.board-header-controls,
.board-actions,
#app-navigation-toggle,
#app-navigation-toggle-custom,
div#controls.ng-scope div.crumb:not(.title),
div#controls.ng-scope div.crumb a.bullet,
a.ng-binding + a,
div.card.create,
.stack__header .action-item,
button.card-options {
display: none !important;
}
#content {
margin: 0;
padding: 0;
}
#app-content {
margin: 0 !important;
}
}
div#app-navigation-toggle.icon-menu {
display:block;
width:0px;
height:0px;
background:none;
}
/* title */
div#controls.ng-scope {padding-left:20px;}
div#controls.ng-scope div.crumb.title {
display:inline;
font-size: 2em;
line-height:2.5em;
background:none;
}
div#controls.ng-scope div.crumb.title a.ng-binding {
color:#000;
opacity:1;
}
/*Due, assigned-users and description*/
div.card-controls {
flex-direction:row;
flex-wrap:wrap;
}
div.card-controls i.icon.icon-filetype-text {background:none;}
div.card-controls i.icon.icon-filetype-text:after {
content: attr(title);
display:block;
width:289px;
height:1.5em;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
div.card-assigned-users {
margin-right:10px;
}
ul.labels li.ng-scope span.ng-binding {
color:#000;
display:inline;
padding-left:5px;
}
/* Layout */
@page {
size: A4 landscape;
margin: 2cm;
}
.board {
max-height: none !important;
overflow: visible !important;
}
div#innerBoard {
display:flex;
flex-wrap: wrap;
}
div.stack.ng-scope.as-sortable-item {border-right: 1px solid #000;}
div#innerBoard.ng-pristine.ng-untouched.ng-valid.ng-scope.ng-not-empty div.stack.ng-scope.as-sortable-item:nth-child(6n) {
page-break-after: always;
}
}

1245
css/style.scss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +0,0 @@
# Nextcloud APIs
## Capabilities
The [Nextcloud Capabilities API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#capabilities-api) provides the following information for the Deck app:
- `version` Current version of the Deck app running
- `canCreateBoards` Ability of the current user to create new boards for themselves
```
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"capabilities": {
"deck": {
"version": "0.8.0",
"canCreateBoards": true
},
}
}
}
}
```
## Available sharees
When sharing a board to a user, group or circle, the possible sharees can be obtained though the files_sharing API.
API endpoint: https://nextcloud.local/index.php/apps/files_sharing/api/v1/sharees
### Parameters
- format: **The response format**
- perPage: **Limit response number**
- itemType: **List of types. Currently supported are**
- 0 user
- 1 group
- 7 circle
## Comments
Comments are stored using the Nextcloud Comments API. You can use the WebDAV endpoint of Nextcloud to fetch, update and delete comments.
### List comments
PROPFIND`remote.php/dav/comments/deckCard/{cardId}`
### Create comment
POST `remote.php/dav/comments/deckCard/{cardId}`
### Update comment
PROPPATCH `remote.php/dav/comments/deckCard/{cardId}/{commentId}`
### Delete comment
DELETE `remote.php/dav/comments/deckCard/{cardId}/{commentId}`
## Activity
The Nextcloud activity app provides an API to fetch activities filtered for deck: [Activity app API documentation](https://github.com/nextcloud/activity/blob/master/docs/endpoint-v2.md)
The deck app offers a filter `deck` to only request activity events that are relevant.

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +0,0 @@
## What is Markdown
The [wikipedia markdown entry](https://en.wikipedia.org/wiki/Markdown) introduced markdown as :
> Markdown is a lightweight markup language with plain text formatting syntax. It is designed so that it can be converted to HTML and many other formats using a tool by the same name. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor. As the initial description of Markdown contained ambiguities and unanswered questions, many implementations and extensions of Markdown appeared over the years to answer these issues.
## Markdown in Deck
The Deck application plugin uses the [markdown-it](https://github.com/markdown-it/markdown-it) script to offer support for markdown in the cards description field.
## Supported Markdown
Markdown comes in may flavors. The best way to learn markdown and understand how to use it, is simply to [try it](https://markdown-it.github.io) on the original script official playground.
That same link offers also a comprehensive list of what is supported, and what is not - rendering it unnecessary to duplicate that content in here.
[CommonMark Markdown Reference](http://commonmark.org/help/)
## Note about checklists
It is possible to create checklists in Deck by writing it in Markdown, using the following syntax:
```md
- [ ] This is a not checked item
- [x] This is a checked item
```
Then, the items can be checked and unchecked by clicking on the rendered checkbox.
Also, a summary of the completed items will be visible at the bottom of the card element.
## Known Issues
As per [issue #127](https://github.com/nextcloud/deck/issues/127) Due to a known limitation of the current script to support markdown, Links that contain the `")"` character will not display well, or will break.
The recommended solution is to use `"<"` and `">"` to wrap those links. It should assure their integrity.
If you come by another case of broken link, or broken display of links, please report it by opening a new issue.

View File

@@ -1,55 +0,0 @@
Releasing a new version works quite easy with [krankerl](https://github.com/ChristophWurst/krankerl) and [github-release](https://github.com/aktau/github-release) installed:
1. Run krankerl to build the package
```
krankerl package
```
2. Tag the release on GitHub
```
# For a prerelease
github-release release -u nextcloud -r deck -t v0.3.1 -p
# For a regular release
github-release release -u nextcloud -r deck -t v0.3.1
```
3. Upload the release package to GitHub
```
github-release upload -u nextcloud -r deck -t v0.3.1 -n deck.tar.gz -f build/artifacts/deck.tar.gz
```
4. Run krankerl to release the package to the app store (add `--nightly` for prerelease packages)
```
krankerl publish https://github.com/nextcloud/deck/releases/download/v0.3.1/deck.tar.gz
```
## Release PR template
```
## Backports
- [ ] ...
## Translations
- [ ] ...
## Release
- [ ] Set proper Nextcloud versions in info.xml
- [ ] Update changelog
- [ ] Build test release
- [ ] Tested on
- [ ] Nextcloud 13
- [ ] Nextcloud 14
- [ ] Nextcloud 15
- [ ] Merge
- [ ] Build final release
- [ ] Publish release
- [ ] Upload to the app store
```

View File

@@ -1,93 +0,0 @@
## Introduction
### What about Deck ?
You may know Kanban website like Trello? Deck is about the same thing but secured and respectful of your privacy!
Integrated in Nextcloud, you can easily manage your projects while having your data secured.
### Use cases
Project management, time management or ideation, Deck makes it easier for you to manage your work.
## Using Deck
Overall, Deck is easy to use. You can create boards, add users, share the Deck, work collaboratively and in real time.
1. [Create my first board](#1-create-my-first-board)
2. [Create stacks and cards](#2-create-stacks-and-cards)
3. [Handle cards options](#3-handle-cards-options)
4. [Archive old tasks](#4-archive-old-tasks)
5. [Manage your board](#5-manage-your-board)
### 1. Create my first board
In this example, we're going to create a board and share it with an other nextcloud user.
![Gif for creating boards](resources/gifs/EN_create_board.gif)
### 2. Create stacks and cards
Stacks are simply columns with list of cards. It can represent a category of tasks or an y step in your projects for example.
**Check this out :**
![Gif for creating columns](resources/gifs/EN_create_columns.gif)
What about the cards? Cards are tasks, objects or ideas that fit into a stack. You can put a lot of cards in a stack! An infinity? Who knows! Who knows!
And all the magic of this software consists on moving your cards from a stack to an other.
**Check this out :**
![Gif for creating tasks](resources/gifs/EN_create_task.gif)
### 3. Handle cards options
Once you have created your cards, you can modify them or add options by clicking on them. So, what are the options? Well, there are several of them:
- Tag Management
- Assign a card to a user (s·he will receive a notification)
- Render date, or deadline
![Gif for puting infos on tasks](resources/gifs/EN_put_infos.gif)
And even :
- Description in markdown language
- Attachment - *you can leave a document, a picture or some other bonus like that.*
![Gif for puting infos on tasks 2](resources/gifs/EN_put_infos_2.gif)
### 4. Archive old tasks
Once finished or obsolete, a task could be archived. The tasks is not deleted, it's just archived, and you can retrieve it later
![Gif for puting infos on tasks 2](resources/gifs/EN_archive.gif)
### 5. Manage your board
You can manage the settings of your Deck once you are inside it, by clicking on the small wheel at the top right.
Once in this menu, you have access to several things:
- Sharing
- Tags
- Deleted objects
- Timeline
The **sharing tab** allows you to add users or even groups to your boards.
**Tags** allows you to modify the tags available for the cards.
**Deleted objects** allows you to return previously deleted stacks or cards.
The **Timeline** allows you to see everything that happened in your boards. Everything!
## Search
Deck provides a global search either through the unified search in the Nextcloud header or with the inline search next to the board controls.
This search allows advanced filtering of cards across all board of the logged in user.
For example the search `project tag:ToDo assigned:alice assigned:bob` will return all cards where the card title or description contains project **and** the tag ToDo is set **and** the user alice is assigned **and** the user bob is assigned.
### Supported search filters
| Filter | Operators | Query |
| ----------- | ----------------- | ------------------------------------------------------------ |
| title | `:` | text token used for a case-insentitive search on the cards title |
| description | `:` | text token used for a case-insentitive search on the cards description |
| list | `:` | text token used for a case-insentitive search on the cards list name |
| tag | `:` | text token used for a case-insentitive search on the assigned tags |
| date | `:` | 'overdue', 'today', 'week', 'month', 'none' |
| | `>` `<` `>=` `<=` | Compare the card due date to the passed date (see [supported date formats](https://www.php.net/manual/de/datetime.formats.php)) Card due dates are always considered UTC for comparison |
| assigned | `:` | id or displayname of a user or group for a search on the assigned users or groups |
Other text tokens will be used to perform a case-insensitive search on the card title and description
In addition wuotes can be used to pass a query with spaces, e.g. `"Exact match with spaces"` or `title:"My card"`.

View File

@@ -1,3 +0,0 @@
.subnav ul {
padding-left: 20px;
}

View File

@@ -1 +0,0 @@
../README.md

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 KiB

View File

@@ -1,6 +0,0 @@
## Database structure
Deck stores most of its data inside of the database. The structure and relationships between entities is documented in the following ER diagram:
![Screenshot](resources/er-diagram.jpg)

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 390 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" version="1.1" height="32" viewbox="0 0 32 32"><path fill="#000" d="m8 2c-1.108 0-2 0.892-2 2v4c0 1.108 0.892 2 2 2s2-0.892 2-2v-4c0-1.108-0.892-2-2-2zm16 0c-1.108 0-2 0.892-2 2v4c0 1.108 0.892 2 2 2s2-0.892 2-2v-4c0-1.108-0.892-2-2-2zm-13 4v2c0 1.662-1.338 3-3 3s-3-1.338-3-3v-1.875a3.993 3.993 0 0 0 -3 3.875v16c0 2.216 1.784 4 4 4h20c2.216 0 4-1.784 4-4v-16a3.993 3.993 0 0 0 -3 -3.875v1.875c0 1.662-1.338 3-3 3s-3-1.338-3-3v-2zm-4.906 10h19.812a0.09 0.09 0 0 1 0.094 0.094v9.812a0.09 0.09 0 0 1 -0.094 0.094h-19.812a0.09 0.09 0 0 1 -0.094 -0.094v-9.812a0.09 0.09 0 0 1 0.094 -0.094z"/></svg>

Before

Width:  |  Height:  |  Size: 646 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 58 58" width="512" height="512"><g fill="#000"><path d="M54.319 37.839C54.762 35.918 55 33.96 55 32c0-9.095-4.631-17.377-12.389-22.153a1 1 0 1 0-1.049 1.703C48.724 15.96 53 23.604 53 32c0 1.726-.2 3.451-.573 5.147A6.992 6.992 0 0 0 51 37c-3.86 0-7 3.141-7 7s3.14 7 7 7 7-3.141 7-7a7.006 7.006 0 0 0-3.681-6.161zM38.171 54.182A23.867 23.867 0 0 1 29 56a24.047 24.047 0 0 1-17.017-7.092A6.974 6.974 0 0 0 14 44c0-3.859-3.14-7-7-7s-7 3.141-7 7 3.14 7 7 7a6.952 6.952 0 0 0 3.381-.875C15.26 55.136 21.994 58 29 58c3.435 0 6.778-.663 9.936-1.971.51-.211.753-.796.542-1.307a1.001 1.001 0 0 0-1.307-.54zM4 31.213a1 1 0 0 0 1.068-.927c.712-10.089 7.586-18.52 17.22-21.314C23.142 11.874 25.825 14 29 14c3.86 0 7-3.141 7-7s-3.14-7-7-7c-3.851 0-6.985 3.127-6.999 6.975C11.42 9.922 3.851 19.12 3.073 30.146A.999.999 0 0 0 4 31.213z"/></g></svg>

Before

Width:  |  Height:  |  Size: 885 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M11.8 13.8H2.2V4.2h9.6m1.2 0c0-.67-.53-1.2-1.2-1.2H2.2C1.53 3 1 3.53 1 4.2v9.6c0 .67.53 1.2 1.2 1.2h9.6c.67 0 1.2-.53 1.2-1.2"/><path d="m4.2 1c-0.67 0-1.2 0.54-1.2 1.2h10.8v10.8c0.67 0 1.2-0.53 1.2-1.2v-9.6c0-0.67-0.53-1.2-1.2-1.2z"/></svg>

Before

Width:  |  Height:  |  Size: 327 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 100 100"><path d="M91.645 8.355c-4.474-4.474-11.727-4.474-16.2 0l-13.5 13.501-3.727-3.727a5.015 5.015 0 1 0-7.093 7.093l3.727 3.727-41.51 41.508a11.411 11.411 0 0 0-3.329 7.324c-.073 1.087-.347 3.105-.675 5.292a1.748 1.748 0 0 1-.487.983l-3.105 3.106a2.546 2.546 0 0 0 0 3.6l3.493 3.493a2.546 2.546 0 0 0 3.6 0l3.106-3.105c.277-.275.622-.433.981-.486 2.187-.329 4.205-.602 5.293-.675a11.412 11.412 0 0 0 7.325-3.33l41.508-41.508 3.727 3.727a5.015 5.015 0 1 0 7.093-7.093L69.507 29.419l9.697 7.577 12.44-12.441c4.475-4.473 4.474-11.726.001-16.2zM65.051 42.749l-20.53 20.53a2.546 2.546 0 0 1-3.6 0l-3.27-3.27a2.545 2.545 0 0 0-3.599.001l-.616.616-.002-.002-14.728 14.727c-.337.337-.819.401-1.076.143s-.194-.74.143-1.076l23.841-23.841.004.004 15.633-15.633a2.546 2.546 0 0 1 3.6 0l4.2 4.201a2.546 2.546 0 0 1 0 3.6z"/></svg>

Before

Width:  |  Height:  |  Size: 897 B

View File

@@ -1 +0,0 @@
<svg width="15" height="15" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M91.645 8.355c-4.474-4.474-11.727-4.474-16.2 0l-13.5 13.501-3.727-3.727a5.015 5.015 0 1 0-7.093 7.093l3.727 3.727-41.51 41.508a11.411 11.411 0 0 0-3.329 7.324c-.073 1.087-.347 3.105-.675 5.292a1.748 1.748 0 0 1-.487.983l-3.105 3.106a2.546 2.546 0 0 0 0 3.6l3.493 3.493a2.546 2.546 0 0 0 3.6 0l3.106-3.105c.277-.275.622-.433.981-.486 2.187-.329 4.205-.602 5.293-.675a11.412 11.412 0 0 0 7.325-3.33l41.508-41.508 3.727 3.727a5.015 5.015 0 1 0 7.093-7.093L69.507 29.419l9.697 7.577 12.44-12.441c4.475-4.473 4.474-11.726.001-16.2zM65.051 42.749l-20.53 20.53a2.546 2.546 0 0 1-3.6 0l-3.27-3.27a2.545 2.545 0 0 0-3.599.001l-.616.616-.002-.002-14.728 14.727c-.337.337-.819.401-1.076.143s-.194-.74.143-1.076l23.841-23.841.004.004 15.633-15.633a2.546 2.546 0 0 1 3.6 0l4.2 4.201a2.546 2.546 0 0 1 0 3.6z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 910 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M14,17L4,17v2h10v-2zM20,9L4,9v2h16L20,9zM4,15h16v-2L4,13v2zM4,5v2h16L20,5L4,5z"/></svg>

Before

Width:  |  Height:  |  Size: 180 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 4.233 4.233"><g paint-order="stroke fill markers"><path d="M.52.465h3.283L2.631 1.918h-.99zM1.642 1.918h.992v1.866l-.996-.455z"/></g></svg>

Before

Width:  |  Height:  |  Size: 216 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4.233 4.233" height="16" width="16"><path d="M.52.465h3.283L2.631 1.918h-.99zm1.122 1.453h.992v1.866l-.996-.455z" paint-order="stroke fill markers"/><ellipse ry=".691" rx=".674" cy="3.461" cx="3.45" fill="#000"/></svg>

Before

Width:  |  Height:  |  Size: 272 B

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" version="1.1" viewBox="0 0 16 16">
<path d="m8 2c-0.5523 0-1 0.4477-1 1 0 0.0472 0.021 0.0873 0.0273 0.1328-1.7366 0.4362-3.0273 1.9953-3.0273 3.8672v2l-1 1v1h10v-1l-1-1v-2c0-1.8719-1.291-3.431-3.0273-3.8672 0.0063-0.0455 0.0273-0.0856 0.0273-0.1328 0-0.5523-0.4477-1-1-1zm-2 10c0 1.1046 0.8954 2 2 2s2-0.8954 2-2z" fill="#000"/>
</svg>

Before

Width:  |  Height:  |  Size: 456 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16"><path d="M15 15s-.4-7.8-7-10V1L1 8l7 7v-4c5.1 0 7 4 7 4z"/></svg>

Before

Width:  |  Height:  |  Size: 128 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -292.77)" display="none" stroke-width=".23666"><rect x=".28112" y="293.43" width="3.7042" height="1.1906" ry=".20225"/><rect x=".26458" y="295.15" width="3.7042" height="1.1906" ry=".20225"/></g><g transform="translate(0 -292.77)"><g transform="matrix(.040404 0 0 .040404 -3.0978 290.01)"><rect x="83.629" y="114.13" width="91.678" height="13.097" stroke-width="3.9049"/><path d="m155.25 81.388-26.194 26.194-26.194-26.154z" stroke-width="6.5484"/><path d="m155.25 159.97-26.194-26.194-26.194 26.154z" stroke-width="6.5484"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 671 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -292.77)" display="none" stroke-width=".23666"><rect x=".28112" y="293.43" width="3.7042" height="1.1906" ry=".20225"/><rect x=".26458" y="295.15" width="3.7042" height="1.1906" ry=".20225"/></g><g transform="translate(0 -292.77)"><g transform="matrix(.040404 0 0 .040404 -3.0978 290.01)"><rect x="83.629" y="114.13" width="91.678" height="13.097" stroke-width="3.9049"/><path d="m155.25 107.58-26.194-26.194-26.194 26.154z" stroke-width="6.5484"/><path d="m155.25 133.78-26.194 26.194-26.194-26.154z" stroke-width="6.5484"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 671 B

79
issue_template.md Normal file
View File

@@ -0,0 +1,79 @@
### Steps to reproduce
1.
2.
3.
### Expected behaviour
Tell us what should happen
### Actual behaviour
Tell us what happens instead
### Server configuration
<!--
You can use the Issue Template application to prefill most of the required information: https://apps.nextcloud.com/apps/issuetemplate
-->
**Operating system**:
**Web server:**
**Database:**
**PHP version:**
**Nextcloud version:** (see Nextcloud admin page)
**Where did you install Nextcloud from:**
**Signing status:**
```
Login as admin user into your Nextcloud and access
http://example.com/index.php/settings/integrity/failed
paste the results here.
```
**List of activated apps:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ app:list
from within your Nextcloud installation folder
```
**Nextcloud configuration:**
```
If you have access to your command line run e.g.:
sudo -u www-data php occ config:list system
from within your Nextcloud installation folder
or
Insert your config.php content here
Make sure to remove all sensitive content such as passwords. (e.g. database password, passwordsalt, secret, smtp password, …)
```
**Are you using an external user-backend, if yes which one:** LDAP/ActiveDirectory/Webdav/...
### Client configuration
**Browser:**
**Operating system:**
### Logs
#### Nextcloud log (data/nextcloud.log)
```
Insert your Nextcloud log here
```
#### Browser log
```
Insert your browser log here, this could for example include:
a) The javascript console log
b) The network log
c) ...
```

3
js/.bowerrc Normal file
View File

@@ -0,0 +1,3 @@
{
"directory": "vendor"
}

49
js/.jshintrc Normal file
View File

@@ -0,0 +1,49 @@
{
"globals": {
"jasmine" : false,
"spyOn" : false,
"it" : false,
"describe" : false,
"expect" : false,
"beforeEach" : false,
"waits" : false,
"waitsFor" : false,
"runs" : false,
"require" : false,
"module": true
},
"asi" : true,
"boss" : true,
"browser" : true,
"curly" : true,
"debug" : true,
"devel" : true,
"eqeqeq" : true,
"eqnull" : false,
"es5" : true,
"evil" : false,
"forin" : true,
"immed" : true,
"indent" : 4,
"jquery" : true,
"latedef" : true,
"laxbreak" : false,
"newcap" : true,
"noarg" : true,
"node" : false,
"noempty" : false,
"nomen" : false,
"nonew" : true,
"onevar" : true,
"plusplus" : false,
"quotmark" : "single",
"regexp" : false,
"strict" : true,
"sub" : true,
"trailing" : true,
"undef" : true,
"unused" : true,
"white" : false,
"scripturl" : true
}

124
js/Gruntfile.js Normal file
View File

@@ -0,0 +1,124 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global module */
module.exports = function(grunt) {
'use strict';
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-wrap');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-phpunit');
grunt.initConfig({
meta: {
pkg: grunt.file.readJSON('package.json'),
version: '<%= meta.pkg.version %>',
configJS: 'config/',
buildJS: [
'app/**/*.js',
'controller/**/*.js',
'filters/**/*.js',
'directive/**/*.js',
'service/**/*.js'
],
productionJS: 'public/',
testsJS: '../tests/js/'
},
concat: {
options: {
stripBanners: true
},
dist: {
src: ['<%= meta.buildJS %>'],
dest: '<%= meta.productionJS %>app.js'
}
},
wrap: {
app: {
src: ['<%= meta.productionJS %>app.js'],
dest: '<%= meta.productionJS %>app.js',
option: {
wrapper: [
'(function(angular, $, oc_requesttoken, undefined){\n\n\'use strict\';\n\n',
'\n})(angular, jQuery, oc_requesttoken);'
]
}
}
},
jshint: {
files: [
'Gruntfile.js',
'<%= meta.buildJS %>**/*.js',
'<%= meta.testsJS %>**/*.js'
],
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
}
},
watch: {
concat: {
files: ['<%=meta.buildJS%>'],
options: {
livereload: true
},
tasks: ['build']
}
},
phpunit: {
classes: {
dir: '../tests/unit'
},
options: {
bootstrap: '../tests/bootstrap.php',
colors: true
}
},
karma: {
unit: {
configFile: '<%= meta.testsJS %>config/karma.js'
},
continuous: {
configFile: '<%= meta.testsJS %>config/karma.js',
browsers: ['Firefox'],
singleRun: true,
reporters: ['progress']
}
},
});
// make tasks available under simpler commands
grunt.registerTask('build', ['jshint', 'concat', 'wrap']);
grunt.registerTask('js-unit', ['karma:continuous']);
};

53
js/app/App.js Normal file
View File

@@ -0,0 +1,53 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global angular */
angular.module('markdown', [])
.provider('markdown', [function () {
var opts = {};
return {
config: function (newOpts) {
opts = newOpts;
},
$get: function () {
return new window.showdown.Converter(opts);
}
};
}])
.filter('markdown', ['markdown', function (markdown) {
return function (text) {
return markdown.makeHtml(text || '');
};
}]);
var app = angular.module('Deck', [
'ngRoute',
'ngSanitize',
'ui.router',
'ui.select',
'as.sortable',
'mdMarkdownIt',
'ngAnimate'
]);

80
js/app/Config.js Normal file
View File

@@ -0,0 +1,80 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app oc_requesttoken markdownitLinkTarget */
app.config(function ($provide, $routeProvider, $interpolateProvider, $httpProvider, $urlRouterProvider, $stateProvider, $compileProvider, markdownItConverterProvider) {
'use strict';
$httpProvider.defaults.headers.common.requesttoken = oc_requesttoken;
$compileProvider.debugInfoEnabled(true);
markdownItConverterProvider.config({
breaks: true,
linkify: true,
xhtmlOut: true
});
markdownItConverterProvider.use(markdownitLinkTarget);
$urlRouterProvider.otherwise('/');
$stateProvider
.state('list', {
url: '/:filter',
templateUrl: '/boardlist.mainView.html',
controller: 'ListController',
reloadOnSearch: false,
params: {
filter: {value: '', dynamic: true}
}
})
.state('board', {
url: '/board/:boardId/:filter',
templateUrl: '/board.html',
controller: 'BoardController',
params: {
filter: {value: '', dynamic: true}
}
})
.state('board.detail', {
url: '/detail/',
reloadOnSearch: false,
params: {
tab: {value: 0, dynamic: true},
},
views: {
'sidebarView': {
templateUrl: '/board.sidebarView.html'
}
}
})
.state('board.card', {
url: '/card/:cardId',
views: {
'sidebarView': {
templateUrl: '/card.sidebarView.html',
controller: 'CardController'
}
}
});
});

82
js/app/Run.js Normal file
View File

@@ -0,0 +1,82 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global Snap */
app.run(function ($document, $rootScope, $transitions, BoardService) {
'use strict';
$document.click(function (event) {
$rootScope.$broadcast('documentClicked', event);
});
$transitions.onEnter({from: 'list'}, function ($state, $transition$) {
BoardService.unsetCurrrent();
});
$transitions.onEnter({to: 'list'}, function ($state, $transition$) {
BoardService.unsetCurrrent();
document.title = "Deck - " + oc_defaults.name;
});
$transitions.onEnter({to: 'board.card'}, function ($state, $transition$) {
$rootScope.sidebar.show = true;
});
$transitions.onEnter({to: 'board.detail'}, function ($state, $transition$) {
$rootScope.sidebar.show = true;
});
$transitions.onEnter({to: 'board'}, function ($state) {
$rootScope.sidebar.show = false;
});
$transitions.onExit({from: 'board.card'}, function ($state) {
$rootScope.sidebar.show = false;
});
$transitions.onExit({from: 'board.detail'}, function ($state) {
$rootScope.sidebar.show = false;
});
$('link[rel="shortcut icon"]').attr(
'href',
OC.filePath('deck', 'img', 'app-512.png')
);
$('#app-navigation-toggle').off('click');
// App sidebar on mobile
var snapper = new Snap({
element: document.getElementById('app-content'),
disable: 'right',
maxPosition: 250,
touchToDrag: false
});
$('#app-navigation-toggle').click(function () {
if ($(window).width() > 768) {
$('#app-navigation').toggle('hidden');
} else {
if (snapper.state().state === 'left') {
snapper.close();
} else {
snapper.open('left');
}
}
});
// Select all elements with data-toggle="tooltips" in the document
$('body').tooltip({
selector: '[data-toggle="tooltip"]'
});
});

29
js/bower.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "deck",
"version": "0.0.1",
"dependencies": {
"angular": "~1.6.1",
"angular-route": "~1.6.1",
"angular-mocks": "~1.6.1",
"angular-sanitize": "~1.6.1",
"angular-animate": "~1.6.1",
"ng-sortable": "1.3.8",
"jquery": "3.2.x",
"es6-shim": "~0.*",
"js-url": "~2.*",
"angular-ui-select": "~0.19.6",
"angular-markdown-it": "~0.6.1",
"angular-ui-router": "~1.0.0",
"markdown-it-link-target": "~1.0.1",
"jquery-timepicker": "883bb2cd94"
},
"license": "AGPL-3.0",
"private": true,
"ignore": [
"'**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@@ -1,36 +1,30 @@
<?php
/**
* @copyright Copyright (c) 2018 Ryan Fletcher <ryan.fletcher@codepassion.ca>
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
namespace OCA\Deck;
use OCP\AppFramework\Http;
class BadRequestException extends StatusException {
public function __construct($message) {
parent::__construct($message);
}
public function getStatus() {
return HTTP::STATUS_BAD_REQUEST;
}
}
/** global: OC */
app.controller('AppController', function ($scope, $location, $http, $route, $log, $rootScope) {
$rootScope.sidebar = {
show: false
};
$scope.sidebar = $rootScope.sidebar;
$scope.user = oc_current_user;
});

View File

@@ -0,0 +1,339 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global oc_defaults OC */
app.controller('BoardController', function ($rootScope, $scope, $stateParams, StatusService, BoardService, StackService, CardService, LabelService, $state, $transitions, $filter) {
$scope.sidebar = $rootScope.sidebar;
$scope.id = $stateParams.boardId;
$scope.status = {
addCard: [],
};
$scope.newLabel = {};
$scope.OC = OC;
$scope.stackservice = StackService;
$scope.boardservice = BoardService;
$scope.cardservice = CardService;
$scope.statusservice = StatusService.getInstance();
$scope.labelservice = LabelService;
$scope.defaultColors = ['31CC7C', '317CCC', 'FF7A66', 'F1DB50', '7C31CC', 'CC317C', '3A3B3D', 'CACBCD'];
$scope.board = BoardService.getCurrent();
// workaround for $stateParams changes not being propagated
$scope.$watch(function() {
return $state.params;
}, function (params) {
$scope.params = params;
}, true);
$scope.params = $state;
$scope.search = function (searchText) {
$scope.searchText = searchText;
$scope.refreshData();
};
$scope.$watch(function () {
if (typeof BoardService.getCurrent() !== 'undefined') {
return BoardService.getCurrent().title;
} else {
return null;
}
}, function () {
$scope.setPageTitle();
});
$scope.setPageTitle = function () {
if (BoardService.getCurrent()) {
document.title = BoardService.getCurrent().title + ' | Deck - ' + oc_defaults.name;
} else {
document.title = 'Deck - ' + oc_defaults.name;
}
};
$scope.statusservice.retainWaiting();
$scope.statusservice.retainWaiting();
// handle filter parameter for switching between archived/unarchived cards
$scope.switchFilter = function (filter) {
$state.go('.', {filter: filter});
};
$scope.$watch(function() {
return $scope.params.filter;
}, function (filter) {
if (filter === 'archive') {
$scope.loadArchived();
} else {
$scope.loadDefault();
}
});
$scope.stacksData = StackService;
$scope.stacks = [];
$scope.$watch('stacksData', function () {
$scope.refreshData();
}, true);
$scope.refreshData = function () {
if ($scope.params.filter === 'archive') {
$scope.filterData('-lastModified', $scope.searchText);
} else {
$scope.filterData('order', $scope.searchText);
}
};
$scope.checkCanEdit = function () {
return !BoardService.getCurrent().archived;
};
// filter cards here, as ng-sortable will not work nicely with html-inline filters
$scope.filterData = function (order, text) {
if ($scope.stacks === undefined) {
return;
}
angular.copy(StackService.getData(), $scope.stacks);
$scope.stacks = $filter('orderBy')($scope.stacks, 'order');
angular.forEach($scope.stacks, function (value, key) {
var cards = $filter('cardSearchFilter')(value.cards, text);
cards = $filter('orderBy')(cards, order);
$scope.stacks[key].cards = cards;
});
};
$scope.loadDefault = function () {
StackService.fetchAll($scope.id).then(function (data) {
$scope.statusservice.releaseWaiting();
}, function (error) {
$scope.statusservice.setError('Error occured', error);
});
};
$scope.loadArchived = function () {
StackService.fetchArchived($scope.id).then(function (data) {
$scope.statusservice.releaseWaiting();
}, function (error) {
$scope.statusservice.setError('Error occured', error);
});
};
// Handle initial Loading
BoardService.fetchOne($scope.id).then(function (data) {
$scope.statusservice.releaseWaiting();
$scope.setPageTitle();
}, function (error) {
$scope.statusservice.setError('Error occured', error);
});
$scope.searchForUser = function (search) {
BoardService.searchUsers(search);
};
$scope.newStack = {'boardId': $scope.id};
$scope.newCard = {};
// Create a new Stack
$scope.createStack = function () {
StackService.create($scope.newStack).then(function (data) {
$scope.newStack.title = "";
});
};
$scope.createCard = function (stack, title) {
var newCard = {
'title': title,
'stackId': stack,
'type': 'plain'
};
CardService.create(newCard).then(function (data) {
$scope.stackservice.addCard(data);
$scope.newCard.title = "";
});
};
$scope.cardDelete = function (card) {
OC.dialogs.confirm(t('deck', 'Are you sure you want to delete this card with all of its data?'), t('deck', 'Delete'), function(state) {
if (!state) {
return;
}
CardService.delete(card.id).then(function () {
StackService.removeCard(card);
});
});
};
$scope.cardArchive = function (card) {
CardService.archive(card);
StackService.removeCard(card);
};
$scope.cardUnarchive = function (card) {
CardService.unarchive(card);
StackService.removeCard(card);
};
$scope.labelDelete = function (label) {
LabelService.delete(label.id);
// remove from board data
var i = BoardService.getCurrent().labels.indexOf(label);
BoardService.getCurrent().labels.splice(i, 1);
// TODO: remove from cards
};
$scope.labelCreate = function (label) {
label.boardId = $scope.id;
LabelService.create(label).then(function (data) {
$scope.newStack.title = "";
BoardService.getCurrent().labels.push(data);
$scope.status.createLabel = false;
$scope.newLabel = {};
});
};
$scope.labelUpdate = function (label) {
label.edit = false;
LabelService.update(label);
};
$scope.aclAdd = function (sharee) {
sharee.boardId = $scope.id;
BoardService.addAcl(sharee);
$scope.status.addSharee = null;
};
$scope.aclDelete = function (acl) {
BoardService.deleteAcl(acl).then(function(data) {
$scope.loadDefault();
$scope.refreshData();
});
};
$scope.aclUpdate = function (acl) {
BoardService.updateAcl(acl);
};
$scope.aclTypeString = function (acl) {
if (typeof acl === 'undefined') {
return '';
}
switch (acl.type) {
case OC.Share.SHARE_TYPE_USER:
return 'user';
case OC.Share.SHARE_TYPE_GROUP:
return 'group';
default:
return '';
}
};
// settings for card sorting
$scope.sortOptions = {
id: 'card',
itemMoved: function (event) {
event.source.itemScope.modelValue.status = event.dest.sortableScope.$parent.column;
var order = event.dest.index;
var card = event.source.itemScope.c;
var newStack = event.dest.sortableScope.$parent.s.id;
var oldStack = card.stackId;
card.stackId = newStack;
CardService.update(card);
CardService.reorder(card, order).then(function (data) {
StackService.addCard(card);
StackService.reorderCard(card, order);
StackService.removeCard({
id: card.id,
stackId: oldStack
});
});
},
orderChanged: function (event) {
var order = event.dest.index;
var card = event.source.itemScope.c;
var stack = event.dest.sortableScope.$parent.s.id;
CardService.reorder(card, order).then(function (data) {
StackService.reorderCard(card, order);
$scope.refreshData();
});
},
scrollableContainer: '#innerBoard',
containerPositioning: 'relative',
containment: '#innerBoard',
longTouch: true,
// auto scroll on drag
dragMove: function (itemPosition, containment, eventObj) {
if (eventObj) {
var container = $("#board");
var offset = container.offset();
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
if (targetX < offset.left) {
container.scrollLeft(container.scrollLeft() - 25);
} else if (targetX > container.width()) {
container.scrollLeft(container.scrollLeft() + 25);
}
if (targetY < offset.top) {
container.scrollTop(container.scrollTop() - 25);
} else if (targetY > container.height()) {
container.scrollTop(container.scrollTop() + 25);
}
}
},
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
return sourceItemHandleScope.sortableScope.options.id === 'card';
}
};
$scope.sortOptionsStack = {
id: 'stack',
orderChanged: function (event) {
var order = event.dest.index;
var stack = event.source.itemScope.s;
StackService.reorder(stack, order).then(function (data) {
$scope.refreshData();
});
},
scrollableContainer: '#board',
containerPositioning: 'relative',
containment: '#innerBoard',
dragMove: function (itemPosition, containment, eventObj) {
if (eventObj) {
var container = $("#board");
var offset = container.offset();
var targetX = eventObj.pageX - (offset.left || container.scrollLeft());
var targetY = eventObj.pageY - (offset.top || container.scrollTop());
if (targetX < offset.left) {
container.scrollLeft(container.scrollLeft() - 50);
} else if (targetX > container.width()) {
container.scrollLeft(container.scrollLeft() + 50);
}
if (targetY < offset.top) {
container.scrollTop(container.scrollTop() - 50);
} else if (targetY > container.height()) {
container.scrollTop(container.scrollTop() + 50);
}
}
},
accept: function (sourceItemHandleScope, destSortableScope, destItemScope) {
return sourceItemHandleScope.sortableScope.options.id === 'stack';
}
};
$scope.labelStyle = function (color) {
return {
'background-color': '#' + color,
'color': $filter('textColorFilter')(color)
};
};
});

View File

@@ -0,0 +1,187 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app moment */
app.controller('CardController', function ($scope, $rootScope, $routeParams, $location, $stateParams, $interval, $timeout, $filter, BoardService, CardService, StackService, StatusService) {
$scope.sidebar = $rootScope.sidebar;
$scope.status = {
lastEdit: 0,
lastSave: Date.now()
};
$scope.cardservice = CardService;
$scope.cardId = $stateParams.cardId;
$scope.statusservice = StatusService.getInstance();
$scope.boardservice = BoardService;
$scope.statusservice.retainWaiting();
CardService.fetchOne($scope.cardId).then(function (data) {
$scope.statusservice.releaseWaiting();
$scope.archived = CardService.getCurrent().archived;
}, function (error) {
});
$scope.cardRenameShow = function () {
if ($scope.archived || !BoardService.canEdit())
{return false;}
else {
$scope.status.cardRename = true;
}
};
$scope.cardEditDescriptionShow = function ($event) {
if (BoardService.isArchived() || CardService.getCurrent().archived) {
return false;
}
if ($scope.card.archived || !$scope.boardservice.canEdit()) {
return false;
}
$scope.status.cardEditDescription = true;
$scope.status.edit = angular.copy(CardService.getCurrent());
return true;
};
$scope.cardEditDescriptionChanged = function ($event) {
$scope.status.lastEdit = Date.now();
var header = $('.section-header.card-description');
header.find('.save-indicator.unsaved').show();
header.find('.save-indicator.saved').hide();
};
$interval(function() {
var currentTime = Date.now();
var timeSinceEdit = currentTime-$scope.status.lastEdit;
if (timeSinceEdit > 1000 && $scope.status.lastEdit > $scope.status.lastSave) {
$scope.status.lastSave = currentTime;
var header = $('.section-header.card-description');
header.find('.save-indicator.unsaved').fadeIn(500);
CardService.update($scope.status.edit).then(function (data) {
var header = $('.section-header.card-description');
header.find('.save-indicator.unsaved').hide();
header.find('.save-indicator.saved').fadeIn(250).fadeOut(1000);
StackService.updateCard($scope.status.edit);
});
}
}, 500, 0, false);
// handle rename to update information on the board as well
$scope.cardRename = function (card) {
CardService.rename(card).then(function (data) {
StackService.updateCard(card);
$scope.status.renameCard = false;
});
};
$scope.cardUpdate = function (card) {
CardService.update(card).then(function (data) {
$scope.status.cardEditDescription = false;
var header = $('.section-content.card-description');
header.find('.save-indicator.unsaved').hide();
header.find('.save-indicator.saved').fadeIn(500).fadeOut(1000);
StackService.updateCard(card);
});
};
$scope.labelAssign = function (element, model) {
CardService.assignLabel($scope.cardId, element.id).then(function (data) {
StackService.updateCard(CardService.getCurrent());
});
};
$scope.labelRemove = function (element, model) {
CardService.removeLabel($scope.cardId, element.id).then(function (data) {
StackService.updateCard(CardService.getCurrent());
});
};
$scope.setDuedate = function (duedate) {
var element = CardService.getCurrent();
var newDate = moment(element.duedate);
if(!newDate.isValid()) {
newDate = moment();
}
newDate.date(duedate.date());
newDate.month(duedate.month());
newDate.year(duedate.year());
element.duedate = newDate.toISOString();
CardService.update(element);
StackService.updateCard(element);
};
$scope.setDuedateTime = function (time) {
var element = CardService.getCurrent();
var newDate = moment(element.duedate);
if(!newDate.isValid()) {
newDate = moment();
}
newDate.hour(time.hour());
newDate.minute(time.minute());
element.duedate = newDate.toISOString();
CardService.update(element);
StackService.updateCard(element);
};
$scope.resetDuedate = function () {
var element = CardService.getCurrent();
element.duedate = null;
CardService.update(element);
StackService.updateCard(element);
};
/**
* Show ui-select field when clicking the add button
*/
$scope.toggleAssignUser = function() {
$scope.status.showAssignUser = !$scope.status.showAssignUser;
if ($scope.status.showAssignUser === true) {
$timeout(function () {
$('#assignUserSelect').find('a').click();
});
}
};
/**
* Hide ui-select when select list is closed
*/
$scope.assingUserOpenClose = function(isOpen) {
$scope.status.showAssignUser = isOpen;
};
$scope.addAssignedUser = function(item) {
CardService.assignUser(CardService.getCurrent(), item.uid).then(function (data) {
StackService.updateCard(CardService.getCurrent());
});
$scope.status.showAssignUser = false;
};
$scope.removeAssignedUser = function(uid) {
CardService.unassignUser(CardService.getCurrent(), uid).then(function (data) {
StackService.updateCard(CardService.getCurrent());
});
};
$scope.labelStyle = function (color) {
return {
'background-color': '#' + color,
'color': $filter('textColorFilter')(color)
};
};
});

View File

@@ -0,0 +1,197 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app angular */
app.controller('ListController', function ($scope, $location, $filter, BoardService, $element, $timeout, $stateParams, $state, StatusService) {
function calculateNewColor() {
var boards = BoardService.getAll();
var boardKeys = Object.keys(boards);
var colorOccurrences = [];
for (var i = 0; i < $scope.colors.length; i++) {
colorOccurrences.push(0);
}
for (var j = 0; j < boardKeys.length; j++) {
var key = boardKeys[j];
var board = boards[key];
if (board && $scope.colors.indexOf(board.color) !== -1) {
colorOccurrences[$scope.colors.indexOf(board.color)]++;
}
}
return $scope.colors[colorOccurrences.indexOf(Math.min.apply(Math, colorOccurrences))];
}
$scope.boards = [];
$scope.newBoard = {};
$scope.status = {
deleteUndo: [],
filter: $stateParams.filter ? $stateParams.filter : '',
sidebar: false
};
$scope.colors = ['0082c9', '00c9c6','00c906', 'c92b00', 'F1DB50', '7C31CC', '3A3B3D', 'CACBCD'];
$scope.boardservice = BoardService;
$scope.updatingBoard = null;
var filterData = function () {
if($element.attr('id') === 'app-navigation') {
$scope.boardservice.sidebar = $scope.boardservice.getData();
$scope.boardservice.sidebar = $filter('orderBy')($scope.boardservice.sidebar, 'title');
$scope.boardservice.sidebar = $filter('cardFilter')($scope.boardservice.sidebar, {archived: false});
} else {
$scope.boardservice.sorted = $scope.boardservice.getData();
if ($scope.status.filter === 'archived') {
var filter = {};
filter[$scope.status.filter] = true;
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, filter);
} else if ($scope.status.filter === 'shared') {
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
$scope.boardservice.sorted = $filter('boardFilterAcl')($scope.boardservice.sorted);
} else {
$scope.boardservice.sorted = $filter('cardFilter')($scope.boardservice.sorted, {archived: false});
}
$scope.boardservice.sorted = $filter('orderBy')($scope.boardservice.sorted, ['deletedAt', 'title']);
}
};
var finishedLoading = function() {
filterData();
$scope.newBoard.color = calculateNewColor();
};
var initialize = function () {
$scope.statusservice = StatusService.listStatus;
if($element.attr('id') === 'app-navigation') {
$scope.statusservice.retainWaiting();
BoardService.fetchAll().then(function(data) {
finishedLoading();
$scope.statusservice.releaseWaiting();
BoardService.loaded = true;
}, function (error) {
$scope.statusservice.setError('Error occured', error);
});
} else {
/* initialize main list controller when board list is loaded */
var boardDataWatch = $scope.$watch(function () {
return $scope.boardservice.loaded;
}, function () {
if (BoardService.loaded === true) {
boardDataWatch();
finishedLoading();
}
});
}
$scope.$watch(function () {
return $scope.boardservice.data;
}, function () {
filterData();
}, true);
/* Watch for board filter change */
$scope.$watchCollection(function(){
return $state.params;
}, function(){
$scope.status.filter = $state.params.filter;
filterData();
});
};
initialize();
$scope.selectColor = function(color) {
$scope.newBoard.color = color;
};
$scope.gotoBoard = function(board) {
if(board.deletedAt > 0) {
return false;
}
return $state.go('board', {boardId: board.id});
};
$scope.boardCreate = function() {
if(!$scope.newBoard.title || !$scope.newBoard.color) {
$scope.status.addBoard=false;
return;
}
BoardService.create($scope.newBoard)
.then(function (response) {
$scope.newBoard = {};
$scope.newBoard.color = calculateNewColor();
$scope.status.addBoard=false;
filterData();
}, function(error) {
$scope.status.createBoard = 'Unable to insert board: ' + error.message;
});
};
$scope.boardUpdate = function(board) {
BoardService.update(board).then(function(data) {
board.status.edit = false;
filterData();
});
};
$scope.boardUpdateBegin = function(board) {
$scope.updatingBoard = angular.copy(board);
};
$scope.boardUpdateReset = function(board) {
board.title = $scope.updatingBoard.title;
board.color = $scope.updatingBoard.color;
filterData();
board.status.edit = false;
};
$scope.boardArchive = function (board) {
board.archived = true;
BoardService.update(board).then(function(data) {
filterData();
});
};
$scope.boardUnarchive = function (board) {
board.archived = false;
BoardService.update(board).then(function(data) {
filterData();
});
};
$scope.boardDelete = function(board) {
BoardService.delete(board.id).then(function (data) {
filterData();
});
};
$scope.boardDeleteUndo = function (board) {
BoardService.deleteUndo(board.id).then(function (data) {
filterData();
});
};
});

View File

@@ -0,0 +1,47 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.directive('appPopoverMenuUtils', function () {
'use strict';
return {
restrict: 'C',
link: function (scope, elm) {
var menu = elm.find('.popovermenu');
var button = elm.find('button');
button.click(function (e) {
var popovermenus = $('.popovermenu');
var shouldShow = menu.hasClass('hidden');
popovermenus.addClass('hidden');
if (shouldShow) {
menu.toggleClass('hidden');
}
e.stopPropagation();
});
scope.$on('documentClicked', function (scope, event) {
/* prevent closing popover if target has no-close class */
if (event.target !== button && !$(event.target).hasClass('no-close')) {
menu.addClass('hidden');
}
});
}
};
});

View File

@@ -0,0 +1,46 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// OwnCloud Click Handling
// https://doc.owncloud.org/server/8.0/developer_manual/app/css.html
app.directive('appNavigationEntryUtils', function () {
'use strict';
return {
restrict: 'C',
link: function (scope, elm) {
var menu = elm.siblings('.app-navigation-entry-menu');
var button = $(elm)
.find('.app-navigation-entry-utils-menu-button button');
button.click(function () {
menu.toggleClass('open');
});
scope.$on('documentClicked', function (scope, event) {
if (event.target !== button[0]) {
menu.removeClass('open');
}
});
}
};
});

View File

@@ -1,26 +1,28 @@
<?php
/**
* @copyright Copyright (c) 2018 Ryan Fletcher <ryan.fletcher@codepassion.ca>
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Ryan Fletcher <ryan.fletcher@codepassion.ca>
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*/
namespace OCA\Deck\Controller;
class AttachmentApiV11Controller extends AttachmentApiController {
}
app.directive('autofocusOnInsert', function () {
'use strict';
return function (scope, elm) {
elm.focus();
};
});

50
js/directive/avatar.js Normal file
View File

@@ -0,0 +1,50 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.directive('avatar', function() {
'use strict';
return {
restrict: 'AEC',
transclude: true,
replace: true,
template: '<div class="avatardiv-container"><div class="avatardiv" data-toggle="tooltip" ng-transclude></div></div>',
scope: { attr: '=' },
link: function(scope, element, attr){
scope.uid = attr.displayname;
scope.displayname = attr.displayname;
var value = attr.user;
var avatardiv = $(element).find('.avatardiv');
if(typeof attr.contactsmenu !== 'undefined' && attr.contactsmenu !== 'false') {
avatardiv.contactsMenu(value, 0, $(element));
avatardiv.addClass('has-contactsmenu');
}
if(typeof attr.tooltip !== 'undefined' && attr.tooltip !== 'false') {
$(element).tooltip({
title: scope.displayname,
placement: 'top'
});
}
avatardiv.avatar(value, 32, false, false, false, attr.displayname);
},
controller: function () {}
};
});

View File

@@ -0,0 +1,41 @@
/*
* @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.directive('contactsmenudelete', function() {
'use strict';
return {
restrict: 'A',
priority: 1,
link: function(scope, element, attr){
var user = attr.user;
var menu = $(element).parent().find('.contactsmenu-popover');
if (oc_current_user === user) {
menu.children(':first').remove();
}
var menuEntry = $('<li><a><span class="icon icon-delete"></span><span>' + t('deck', 'Remove user from card') + '</span></a></li>');
menuEntry.on('click', function () {
scope.removeAssignedUser(user);
});
$(menu).append(menuEntry);
}
};
});

View File

@@ -0,0 +1,53 @@
/*
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app */
/* gloabl t */
/* global moment */
app.directive('datepicker', function () {
'use strict';
return {
link: function (scope, elm, attr) {
return elm.datepicker({
dateFormat: 'yy-mm-dd',
onSelect: function(date, inst) {
scope.setDuedate(moment(date));
scope.$apply();
},
beforeShow: function(input, inst) {
var dp, marginLeft;
dp = $(inst).datepicker('widget');
marginLeft = -Math.abs($(input).outerWidth() - dp.outerWidth()) / 2 + 'px';
dp.css({
'margin-left': marginLeft
});
$('div.ui-datepicker:before').css({
'left': 100 + 'px'
});
return $('.hasDatepicker').datepicker();
},
minDate: null
});
}
};
});

40
js/directive/elastic.js Normal file
View File

@@ -0,0 +1,40 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// original idea from blockloop: http://stackoverflow.com/a/24090733
app.directive('elastic', [
'$timeout',
function($timeout) {
return {
restrict: 'A',
link: function($scope, element) {
$scope.initialHeight = $scope.initialHeight || element[0].style.height;
var resize = function() {
element[0].style.height = $scope.initialHeight;
element[0].style.height = "" + element[0].scrollHeight + "px";
};
element.on("input change", resize);
$timeout(resize, 0);
}
};
}
]);

50
js/directive/search.js Normal file
View File

@@ -0,0 +1,50 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.directive('search', function ($document, $location) {
'use strict';
return {
restrict: 'E',
scope: {
'onSearch': '='
},
link: function (scope) {
var box = $('#searchbox');
box.val($location.search().search);
var doSearch = function() {
var value = box.val();
scope.$apply(function () {
scope.onSearch(value);
});
};
box.on('search keyup', function (event) {
if (event.type === 'search' || event.keyCode === 13 ) {
doSearch();
}
});
}
};
});

View File

@@ -1,5 +1,4 @@
<?php
/**
/*
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
@@ -21,25 +20,26 @@
*
*/
namespace OCA\Deck\Db;
/* global app */
/* global t */
/* global moment */
class Circle extends RelationalObject {
/** @var \OCA\Circles\Model\Circle */
protected $object;
public function __construct(\OCA\Circles\Model\Circle $circle) {
$primaryKey = $circle->getUniqueId();
parent::__construct($primaryKey, $circle);
}
public function getObjectSerialization() {
return [
'uid' => $this->object->getUniqueId(),
'displayname' => $this->object->getName(),
'typeString' => $this->object->getTypeString(),
'circleOwner' => $this->object->getOwner(),
'type' => 7
];
}
}
app.directive('timepicker', function() {
'use strict';
return {
restrict: 'A',
link: function(scope, elm, attr) {
return elm.timepicker({
onSelect: function(date, inst) {
scope.setDuedateTime(moment('2000-01-01 ' + date));
scope.$apply();
},
myPosition: 'center top',
atPosition: 'center bottom',
hourText: t('deck', 'Hours'),
minuteText: t('deck', 'Minutes'),
showPeriodLabels: false
});
}
};
});

View File

@@ -0,0 +1,33 @@
/*
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('boardFilterAcl', function() {
return function(boards) {
var _result = [];
angular.forEach(boards, function(board){
if(board.acl !== null && Object.keys(board.acl).length > 0) {
_result.push(board);
}
});
return _result;
};
});

39
js/filters/cardFilter.js Normal file
View File

@@ -0,0 +1,39 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// usage | cardFilter({ member: 'admin'})
app.filter('cardFilter', function() {
return function(cards, rules) {
var _result = [];
angular.forEach(cards, function(card){
var _card = card;
var keys = Object.keys(rules);
keys.some(function(key, condition) {
if(_card[key]===rules[key]) {
_result.push(_card);
}
});
});
return _result;
};
});

View File

@@ -0,0 +1,43 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('cardSearchFilter', function() {
return function(cards, searchString) {
var _result = {};
var rules = {
title: searchString,
//owner: searchString,
};
angular.forEach(cards, function(card){
var _card = card;
Object.keys(rules).some(function(rule) {
if(_card[rule].search(rules[rule])>=0) {
_result[_card.id] = _card;
}
});
});
return $.map(_result, function(value, index) {
return [value];
});
};
});

61
js/filters/dateFilters.js Normal file
View File

@@ -0,0 +1,61 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app */
/* global OC */
/* global moment */
app.filter('relativeDateFilter', function() {
return function (timestamp) {
return OC.Util.relativeModifiedDate(timestamp*1000);
};
});
app.filter('relativeDateFilterString', function() {
return function (date) {
return OC.Util.relativeModifiedDate(Date.parse(date));
};
});
app.filter('dateToTimestamp', function() {
return function (date) {
return Date.parse(date);
};
});
app.filter('parseDate', function() {
return function (date) {
if(moment(date).isValid()) {
return moment(date).format('YYYY-MM-DD');
}
return '';
};
});
app.filter('parseTime', function() {
return function (date) {
if(moment(date).isValid()) {
return moment(date).format('HH:mm');
}
return '';
};
});

View File

@@ -0,0 +1,66 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('iconWhiteFilter', function () {
return function (hex) {
// RGB2HLS by Garry Tan
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
var color = result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
if (result === null) {
return "";
}
var r = color.r / 255;
var g = color.g / 255;
var b = color.b / 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
if (l < 0.5) {
return "-white";
} else {
return "";
}
};
});

View File

@@ -0,0 +1,37 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('lightenColorFilter', function() {
return function (hex) {
var result = /^([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
var color = result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
if (result !== null) {
return "rgba(" + color.r + "," + color.g + "," + color.b + ",0.7)";
} else {
return "#" + hex;
}
};
});

View File

@@ -0,0 +1,42 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('orderObjectBy', function(){
return function(input, attribute) {
if (!angular.isObject(input)) {
return input;
}
var array = [];
for(var objectKey in input) {
if ({}.hasOwnProperty.call(input, objectKey)) {
array.push(input[objectKey]);
}
}
array.sort(function(a, b){
a = parseInt(a[attribute]);
b = parseInt(b[attribute]);
return a < b;
});
return array;
};
});

View File

@@ -0,0 +1,68 @@
/*
* @copyright Copyright (c) 2016 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
app.filter('textColorFilter', function () {
return function (hex) {
// RGB2HLS by Garry Tan
// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
var result = /^#?([A-Fa-f\d]{2})([A-Fa-f\d]{2})([A-Fa-f\d]{2})$/i.exec(hex);
var color = result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
if (result !== null) {
var r = color.r / 255;
var g = color.g / 255;
var b = color.b / 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max === min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
if (l < 0.5) {
return "#ffffff";
} else {
return "#000000";
}
} else {
return "#000000";
}
};
});

View File

@@ -0,0 +1,45 @@
/*
* @copyright Copyright (c) 2017 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* global app */
/* global angular */
/*
* Remove all assignedUsers from users list
*/
app.filter('withoutAssignedUsers', function () {
return function (users, assignedUsers) {
var _result = [];
angular.forEach(users, function (user) {
var _found = false;
angular.forEach(assignedUsers, function (assignedUser) {
if (assignedUser.participant.uid === user.uid) {
_found = true;
}
});
if (_found === false) {
_result.push(user);
}
});
return _result;
};
});

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