Merge pull request #11575 from nextcloud/stb14-add-group-settings

[stable14] Add new group entry on users list + fixes
This commit is contained in:
Morris Jobke 2018-10-03 14:53:48 +02:00 committed by GitHub
commit 0ca305b1c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 300 additions and 309 deletions

View File

@ -1377,21 +1377,6 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
/* USERS LIST -------------------------------------------------------------- */ /* USERS LIST -------------------------------------------------------------- */
#body-settings { #body-settings {
#app-navigation {
/* Hack to override the javascript orderBy */
#usergrouplist > li {
order: 4;
&#everyone {
order:1;
}
&#admin {
order:2;
}
&#disabled {
order:3;
}
}
}
$grid-row-height: 46px; $grid-row-height: 46px;
#app-content.user-list-grid { #app-content.user-list-grid {
display: grid; display: grid;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{ {
"name": "settings", "name": "settings",
"version": "1.2.2", "version": "1.2.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1526,7 +1526,7 @@
}, },
"browserify-aes": { "browserify-aes": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -1563,7 +1563,7 @@
}, },
"browserify-rsa": { "browserify-rsa": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -1597,7 +1597,7 @@
}, },
"buffer": { "buffer": {
"version": "4.9.1", "version": "4.9.1",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true, "dev": true,
"requires": { "requires": {
@ -1913,7 +1913,7 @@
}, },
"create-hash": { "create-hash": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -1926,7 +1926,7 @@
}, },
"create-hmac": { "create-hmac": {
"version": "1.1.7", "version": "1.1.7",
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2123,7 +2123,7 @@
}, },
"diffie-hellman": { "diffie-hellman": {
"version": "5.0.3", "version": "5.0.3",
"resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -2278,7 +2278,7 @@
}, },
"events": { "events": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "http://registry.npmjs.org/events/-/events-1.1.1.tgz", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
"dev": true "dev": true
}, },
@ -2455,6 +2455,11 @@
"integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
"dev": true "dev": true
}, },
"fecha": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
},
"file-loader": { "file-loader": {
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz",
@ -2589,7 +2594,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -2610,12 +2616,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -2630,17 +2638,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -2757,7 +2768,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -2769,6 +2781,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -2783,6 +2796,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -2790,12 +2804,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.2.4", "version": "2.2.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -2814,6 +2830,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -2894,7 +2911,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -2906,6 +2924,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -2991,7 +3010,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.1", "version": "5.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -3027,6 +3047,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -3046,6 +3067,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -3089,12 +3111,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.2", "version": "3.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },
@ -3560,7 +3584,7 @@
}, },
"is-obj": { "is-obj": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true "dev": true
}, },
@ -3979,6 +4003,18 @@
"integrity": "sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw==", "integrity": "sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw==",
"dev": true "dev": true
}, },
"nextcloud-vue": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.1.5.tgz",
"integrity": "sha512-2tFfPPzhTMtZnbBmUk91o2o+jiri3X6BEgNs+iAWf9WZq4Gcpb6kIFW2ckizZuPFccmV1rA4Ts18IpU25vGERw==",
"requires": {
"@babel/polyfill": "^7.0.0",
"v-tooltip": "^2.0.0-rc.33",
"vue": "^2.5.16",
"vue-click-outside": "^1.0.7",
"vue2-datepicker": "^2.4.1"
}
},
"nice-try": { "nice-try": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
@ -4209,7 +4245,7 @@
}, },
"parse-asn1": { "parse-asn1": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
"integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -4449,7 +4485,7 @@
}, },
"public-encrypt": { "public-encrypt": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "http://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
"integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -4520,7 +4556,7 @@
}, },
"readable-stream": { "readable-stream": {
"version": "2.3.6", "version": "2.3.6",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -4773,7 +4809,7 @@
}, },
"sha.js": { "sha.js": {
"version": "2.4.11", "version": "2.4.11",
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true, "dev": true,
"requires": { "requires": {
@ -5085,9 +5121,9 @@
"dev": true "dev": true
}, },
"tapable": { "tapable": {
"version": "1.1.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz",
"integrity": "sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA==", "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==",
"dev": true "dev": true
}, },
"through2": { "through2": {
@ -5485,9 +5521,9 @@
"integrity": "sha512-29YQVVkIdoS6BZBCJAyu9d0OR0eKSm5gk5OjsLssV1+NM4zJnf9cxhN1AVeXkUHJLqOonECweuaR8PZ2x307dw==" "integrity": "sha512-29YQVVkIdoS6BZBCJAyu9d0OR0eKSm5gk5OjsLssV1+NM4zJnf9cxhN1AVeXkUHJLqOonECweuaR8PZ2x307dw=="
}, },
"vue-multiselect": { "vue-multiselect": {
"version": "2.1.0", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.0.tgz", "resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.2.tgz",
"integrity": "sha512-mEhApxZ6MUISGLuGDy0RF5UlAKUgG/Qq0DWYE/C+CA1h6ZszM3cHfpNFfFm2AMWLclY2SAWpY1HlQLjsw8WnvQ==" "integrity": "sha512-pTJ8s7DYhvvWxolexPfNBPjpF5x7rFa3mwhqgDFZrNxDkyQvY6g7FWuY+IsbqT4LBF4uL6p7q0nh3Q4vobWW0w=="
}, },
"vue-resize": { "vue-resize": {
"version": "0.4.4", "version": "0.4.4",
@ -5525,6 +5561,14 @@
"integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==", "integrity": "sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==",
"dev": true "dev": true
}, },
"vue2-datepicker": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/vue2-datepicker/-/vue2-datepicker-2.4.3.tgz",
"integrity": "sha512-Tw6k7AZyCl698CQgrNFKzHy1po6LVHYXBw+gQ3yozsxbpX6TCdq7MasvSpP5q0cQxgs8COlIZr1x4EjIKYjejQ==",
"requires": {
"fecha": "^2.3.3"
}
},
"vuex": { "vuex": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz", "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.0.1.tgz",
@ -5576,6 +5620,14 @@
"uglifyjs-webpack-plugin": "^1.2.4", "uglifyjs-webpack-plugin": "^1.2.4",
"watchpack": "^1.5.0", "watchpack": "^1.5.0",
"webpack-sources": "^1.3.0" "webpack-sources": "^1.3.0"
},
"dependencies": {
"tapable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.0.tgz",
"integrity": "sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA==",
"dev": true
}
} }
}, },
"webpack-cli": { "webpack-cli": {
@ -5680,7 +5732,7 @@
}, },
"wrap-ansi": { "wrap-ansi": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true, "dev": true,
"requires": { "requires": {

View File

@ -1,7 +1,7 @@
{ {
"name": "settings", "name": "settings",
"description": "Nextcloud settings", "description": "Nextcloud settings",
"version": "1.2.2", "version": "1.2.3",
"author": "John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>", "author": "John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>",
"license": "AGPL3", "license": "AGPL3",
"private": true, "private": true,
@ -13,12 +13,13 @@
"dependencies": { "dependencies": {
"@babel/polyfill": "^7.0.0", "@babel/polyfill": "^7.0.0",
"axios": "^0.18.0", "axios": "^0.18.0",
"nextcloud-vue": "^0.1.5",
"v-tooltip": "^2.0.0-rc.33", "v-tooltip": "^2.0.0-rc.33",
"vue": "^2.5.17", "vue": "^2.5.17",
"vue-click-outside": "^1.0.7", "vue-click-outside": "^1.0.7",
"vue-infinite-loading": "^2.3.3", "vue-infinite-loading": "^2.3.3",
"vue-localstorage": "^0.6.2", "vue-localstorage": "^0.6.2",
"vue-multiselect": "^2.1.0", "vue-multiselect": "^2.1.2",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vuex": "^3.0.1", "vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0" "vuex-router-sync": "^5.0.0"

View File

@ -1,54 +0,0 @@
<!--
- @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
-
- @author John Molakvoæ <skjnldsv@protonmail.com>
-
- @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/>.
-
-->
<template>
<div id="app-navigation" :class="{'icon-loading': menu.loading}">
<div class="app-navigation-new" v-if="menu.new">
<button type="button" :id="menu.new.id" :class="menu.new.icon" @click="menu.new.action">{{menu.new.text}}</button>
</div>
<ul :id="menu.id">
<navigation-item v-for="item in menu.items" :item="item" :key="item.key" />
</ul>
<div id="app-settings" v-if="!!$slots['settings-content']">
<div id="app-settings-header">
<button class="settings-button"
data-apps-slide-toggle="#app-settings-content"
>{{t('settings', 'Settings')}}</button>
</div>
<div id="app-settings-content">
<slot name="settings-content"></slot>
</div>
</div>
</div>
</template>
<script>
import navigationItem from './appNavigation/navigationItem';
export default {
name: 'appNavigation',
props: ['menu'],
components: {
navigationItem
}
};
</script>

View File

@ -1,155 +0,0 @@
<!--
- @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com>
-
- @author John Molakvoæ <skjnldsv@protonmail.com>
-
- @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/>.
-
-->
<template>
<!-- Is this a caption ? -->
<li class="app-navigation-caption" v-if="item.caption">{{item.text}}</li>
<!-- Navigation item -->
<nav-element v-else :id="item.id" v-bind="navElement(item)"
:class="[{'icon-loading-small': item.loading, 'open': item.opened, 'collapsible': item.collapsible&&item.children&&item.children.length>0 }, item.classes]">
<!-- Bullet -->
<div v-if="item.bullet" class="app-navigation-entry-bullet" :style="{ backgroundColor: item.bullet }"></div>
<!-- Main link -->
<a :href="(item.href) ? item.href : '#' " @click="toggleCollapse" :class="item.icon">
<img v-if="item.iconUrl" :alt="item.text" :src="item.iconUrl">
{{item.text}}
</a>
<!-- Popover, counter and button(s) -->
<div v-if="item.utils" class="app-navigation-entry-utils">
<ul>
<!-- counter -->
<li v-if="Number.isInteger(item.utils.counter)"
class="app-navigation-entry-utils-counter">{{item.utils.counter}}</li>
<!-- first action if only one action -->
<li v-if="item.utils.actions && item.utils.actions.length === 1"
class="app-navigation-entry-utils-menu-button">
<button @click="item.utils.actions[0].action" :class="item.utils.actions[0].icon" :title="item.utils.actions[0].text"></button>
</li>
<!-- second action only two actions and no counter -->
<li v-else-if="item.utils.actions && item.utils.actions.length === 2 && !Number.isInteger(item.utils.counter)"
v-for="action in item.utils.actions" :key="action.action"
class="app-navigation-entry-utils-menu-button">
<button @click="action.action" :class="action.icon" :title="action.text"></button>
</li>
<!-- menu if only at least one action and counter OR two actions and no counter-->
<li v-else-if="item.utils.actions && item.utils.actions.length > 1 && (Number.isInteger(item.utils.counter) || item.utils.actions.length > 2)"
class="app-navigation-entry-utils-menu-button">
<button v-click-outside="hideMenu" @click="showMenu" ></button>
</li>
</ul>
</div>
<!-- if more than 2 actions or more than 1 actions with counter -->
<div v-if="item.utils && item.utils.actions && item.utils.actions.length > 1 && (Number.isInteger(item.utils.counter) || item.utils.actions.length > 2)"
class="app-navigation-entry-menu" :class="{ 'open': openedMenu }">
<popover-menu :menu="item.utils.actions"/>
</div>
<!-- undo entry -->
<div class="app-navigation-entry-deleted" v-if="item.undo">
<div class="app-navigation-entry-deleted-description">{{item.undo.text}}</div>
<button class="app-navigation-entry-deleted-button icon-history" :title="t('settings', 'Undo')"></button>
</div>
<!-- edit entry -->
<div class="app-navigation-entry-edit" v-if="item.edit">
<form>
<input type="text" v-model="item.text">
<input type="submit" value="" class="icon-confirm">
<input type="submit" value="" class="icon-close" @click.stop.prevent="cancelEdit">
</form>
</div>
<!-- if the item has children, inject the component with proper data -->
<ul v-if="item.children">
<navigation-item v-for="(item, key) in item.children" :item="item" :key="key" />
</ul>
</nav-element>
</template>
<script>
import popoverMenu from '../popoverMenu';
import ClickOutside from 'vue-click-outside';
import Vue from 'vue';
export default {
name: 'navigationItem',
props: ['item'],
components: {
popoverMenu
},
directives: {
ClickOutside
},
data() {
return {
openedMenu: false
};
},
methods: {
showMenu() {
this.openedMenu = true;
},
hideMenu() {
this.openedMenu = false;
},
toggleCollapse() {
// if item.opened isn't set, Vue won't trigger view updates https://vuejs.org/v2/api/#Vue-set
// ternary is here to detect the undefined state of item.opened
Vue.set(this.item, 'opened', this.item.opened ? !this.item.opened : true);
},
cancelEdit() {
// remove the editing class
if (Array.isArray(this.item.classes))
this.item.classes = this.item.classes.filter(
item => item !== 'editing'
);
},
// This is used to decide which outter element type to use
// li or router-link
navElement(item) {
if (item.href) {
return {
is: 'li'
};
}
return {
is: 'router-link',
tag: 'li',
to: item.router,
exact: true
};
}
},
mounted() {
// prevent click outside event with popupItem.
this.popupItem = this.$el;
}
};
</script>

View File

@ -44,9 +44,9 @@
</div> </div>
<form class="row" id="new-user" v-show="showConfig.showNewUserForm" <form class="row" id="new-user" v-show="showConfig.showNewUserForm"
v-on:submit.prevent="createUser" :disabled="loading" v-on:submit.prevent="createUser" :disabled="loading.all"
:class="{'sticky': scrolled && showConfig.showNewUserForm}"> :class="{'sticky': scrolled && showConfig.showNewUserForm}">
<div :class="loading?'icon-loading-small':'icon-add'"></div> <div :class="loading.all?'icon-loading-small':'icon-add'"></div>
<div class="name"> <div class="name">
<input id="newusername" type="text" required v-model="newUser.id" <input id="newusername" type="text" required v-model="newUser.id"
:placeholder="t('settings', 'Username')" name="username" :placeholder="t('settings', 'Username')" name="username"
@ -74,12 +74,13 @@
<div class="groups"> <div class="groups">
<!-- hidden input trick for vanilla html5 form validation --> <!-- hidden input trick for vanilla html5 form validation -->
<input type="text" :value="newUser.groups" v-if="!settings.isAdmin" <input type="text" :value="newUser.groups" v-if="!settings.isAdmin"
tabindex="-1" id="newgroups" :required="!settings.isAdmin" /> tabindex="-1" id="newgroups" :required="!settings.isAdmin"
<multiselect :options="canAddGroups" v-model="newUser.groups" :class="{'icon-loading-small': loading.groups}"/>
:placeholder="t('settings', 'Add user in group')" <multiselect v-model="newUser.groups" :options="canAddGroups" :disabled="loading.groups||loading.all"
label="name" track-by="id" class="multiselect-vue" tag-placeholder="create" :placeholder="t('settings', 'Add user in group')"
:multiple="true" :close-on-select="false" label="name" track-by="id" class="multiselect-vue"
:allowEmpty="settings.isAdmin"> :multiple="true" :taggable="true" :close-on-select="false"
@tag="createGroup">
<!-- If user is not admin, he is a subadmin. <!-- If user is not admin, he is a subadmin.
Subadmins can't create users outside their groups Subadmins can't create users outside their groups
Therefore, empty select is forbidden --> Therefore, empty select is forbidden -->
@ -154,7 +155,10 @@ export default {
return { return {
unlimitedQuota: unlimitedQuota, unlimitedQuota: unlimitedQuota,
defaultQuota: defaultQuota, defaultQuota: defaultQuota,
loading: false, loading: {
all: false,
groups: false
},
scrolled: false, scrolled: false,
searchQuery: '', searchQuery: '',
newUser: { newUser: {
@ -318,10 +322,10 @@ export default {
resetForm() { resetForm() {
// revert form to original state // revert form to original state
Object.assign(this.newUser, this.$options.data.call(this).newUser); Object.assign(this.newUser, this.$options.data.call(this).newUser);
this.loading = false; this.loading.all = false;
}, },
createUser() { createUser() {
this.loading = true; this.loading.all = true;
this.$store.dispatch('addUser', { this.$store.dispatch('addUser', {
userid: this.newUser.id, userid: this.newUser.id,
password: this.newUser.password, password: this.newUser.password,
@ -332,7 +336,7 @@ export default {
quota: this.newUser.quota.id, quota: this.newUser.quota.id,
language: this.newUser.language.code, language: this.newUser.language.code,
}).then(() => this.resetForm()) }).then(() => this.resetForm())
.catch(() => this.loading = false); .catch(() => this.loading.all = false);
}, },
setNewUserDefaultGroup(value) { setNewUserDefaultGroup(value) {
if (value && value.length > 0) { if (value && value.length > 0) {
@ -345,6 +349,25 @@ export default {
} }
// fallback, empty selected group // fallback, empty selected group
this.newUser.groups = []; this.newUser.groups = [];
},
/**
* Create a new group
*
* @param {string} groups Group id
* @returns {Promise}
*/
createGroup(gid) {
this.loading.groups = true;
this.$store.dispatch('addGroup', gid)
.then((group) => {
this.newUser.groups.push(this.groups.find(group => group.id === gid))
this.loading.groups = false;
})
.catch(() => {
this.loading.groups = false;
});
return this.$store.getters.getGroups[this.groups.length];
} }
} }
} }

View File

@ -296,7 +296,10 @@ const actions = {
addGroup(context, gid) { addGroup(context, gid) {
return api.requireAdmin().then((response) => { return api.requireAdmin().then((response) => {
return api.post(OC.linkToOCS(`cloud/groups`, 2), {groupid: gid}) return api.post(OC.linkToOCS(`cloud/groups`, 2), {groupid: gid})
.then((response) => context.commit('addGroup', {gid: gid, displayName: gid})) .then((response) => {
context.commit('addGroup', {gid: gid, displayName: gid})
return {gid: gid, displayName: gid}
})
.catch((error) => {throw error;}); .catch((error) => {throw error;});
}).catch((error) => { }).catch((error) => {
context.commit('API_FAILURE', { gid, error }); context.commit('API_FAILURE', { gid, error });

View File

@ -34,7 +34,7 @@
<script> <script>
import appNavigation from '../components/appNavigation'; import { AppNavigation } from 'nextcloud-vue';
import appList from '../components/appList'; import appList from '../components/appList';
import Vue from 'vue'; import Vue from 'vue';
import VueLocalStorage from 'vue-localstorage' import VueLocalStorage from 'vue-localstorage'
@ -42,7 +42,6 @@ import Multiselect from 'vue-multiselect';
import api from '../store/api'; import api from '../store/api';
import AppDetails from '../components/appDetails'; import AppDetails from '../components/appDetails';
Vue.use(VueLocalStorage)
Vue.use(VueLocalStorage) Vue.use(VueLocalStorage)
export default { export default {
@ -59,7 +58,7 @@ export default {
}, },
components: { components: {
AppDetails, AppDetails,
appNavigation, AppNavigation,
appList, appList,
}, },
methods: { methods: {

View File

@ -57,21 +57,20 @@
</template> </template>
<script> <script>
import appNavigation from '../components/appNavigation'; import { AppNavigation } from 'nextcloud-vue';
import userList from '../components/userList'; import userList from '../components/userList';
import Vue from 'vue'; import Vue from 'vue';
import VueLocalStorage from 'vue-localstorage' import VueLocalStorage from 'vue-localstorage'
import Multiselect from 'vue-multiselect'; import Multiselect from 'vue-multiselect';
import api from '../store/api'; import api from '../store/api';
Vue.use(VueLocalStorage)
Vue.use(VueLocalStorage) Vue.use(VueLocalStorage)
export default { export default {
name: 'Users', name: 'Users',
props: ['selectedGroup'], props: ['selectedGroup'],
components: { components: {
appNavigation, AppNavigation,
userList, userList,
Multiselect Multiselect
}, },
@ -101,6 +100,8 @@ export default {
// temporary value used for multiselect change // temporary value used for multiselect change
selectedQuota: false, selectedQuota: false,
externalActions: [], externalActions: [],
showAddGroupEntry: false,
loadingAddGroup: false,
showConfig: { showConfig: {
showStoragePath: false, showStoragePath: false,
showUserBackend: false, showUserBackend: false,
@ -198,6 +199,24 @@ export default {
action: action action: action
}); });
return this.externalActions; return this.externalActions;
},
/**
* Create a new group
*
* @param {Object} event The form submit event
*/
createGroup(event) {
let gid = event.target[0].value;
this.loadingAddGroup = true;
this.$store.dispatch('addGroup', gid)
.then(() => {
this.showAddGroupEntry = false;
this.loadingAddGroup = false;
})
.catch(() => {
this.loadingAddGroup = false;
});
} }
}, },
computed: { computed: {
@ -276,6 +295,7 @@ export default {
// BUILD APP NAVIGATION MENU OBJECT // BUILD APP NAVIGATION MENU OBJECT
menu() { menu() {
// Data provided php side // Data provided php side
let self = this;
let groups = this.$store.getters.getGroups; let groups = this.$store.getters.getGroups;
groups = Array.isArray(groups) ? groups : []; groups = Array.isArray(groups) ? groups : [];
@ -302,31 +322,19 @@ export default {
if (item.id !== 'admin' && item.id !== 'disabled' && this.settings.isAdmin) { if (item.id !== 'admin' && item.id !== 'disabled' && this.settings.isAdmin) {
// add delete button on real groups // add delete button on real groups
let self = this;
item.utils.actions = [{ item.utils.actions = [{
icon: 'icon-delete', icon: 'icon-delete',
text: t('settings', 'Remove group'), text: t('settings', 'Remove group'),
action: function() {self.removeGroup(group.id)} action: function() {
self.removeGroup(group.id)
}
}]; }];
}; };
return item; return item;
}); });
// Adjust data // Every item is added on top of the array, so we're going backward
let adminGroup = groups.find(group => group.id == 'admin'); // Groups, separator, disabled, admin, everyone
let disabledGroupIndex = groups.findIndex(group => group.id == 'disabled');
let disabledGroup = groups[disabledGroupIndex];
if (adminGroup && adminGroup.text) {
adminGroup.text = t('settings', 'Admins'); // rename admin group
adminGroup.icon = 'icon-user-admin'; // set icon
}
if (disabledGroup && disabledGroup.text) {
disabledGroup.text = t('settings', 'Disabled users'); // rename disabled group
disabledGroup.icon = 'icon-disabled-users'; // set icon
if (!disabledGroup.utils.counter) {
groups.splice(disabledGroupIndex, 1); // remove disabled if empty
}
}
// Add separator // Add separator
let realGroups = groups.find((group) => {return group.id !== 'disabled' && group.id !== 'admin'}); let realGroups = groups.find((group) => {return group.id !== 'disabled' && group.id !== 'admin'});
@ -340,6 +348,26 @@ export default {
groups.unshift(separator); groups.unshift(separator);
} }
// Adjust admin and disabled groups
let adminGroup = groups.find(group => group.id == 'admin');
let disabledGroup = groups.find(group => group.id == 'disabled');
// filter out admin and disabled
groups = groups.filter(group => ['admin', 'disabled'].indexOf(group.id) === -1);
if (adminGroup && adminGroup.text) {
adminGroup.text = t('settings', 'Admins'); // rename admin group
adminGroup.icon = 'icon-user-admin'; // set icon
groups.unshift(adminGroup); // add admin group if present
}
if (disabledGroup && disabledGroup.text) {
disabledGroup.text = t('settings', 'Disabled users'); // rename disabled group
disabledGroup.icon = 'icon-disabled-users'; // set icon
if (disabledGroup.utils && disabledGroup.utils.counter > 0) {
groups.unshift(disabledGroup); // add disabled if not empty
}
}
// Add everyone group // Add everyone group
let everyoneGroup = { let everyoneGroup = {
@ -351,10 +379,35 @@ export default {
}; };
// users count // users count
if (this.userCount > 0) { if (this.userCount > 0) {
everyoneGroup.utils = {counter: this.userCount}; Vue.set(everyoneGroup, 'utils', {
counter: this.userCount
});
} }
groups.unshift(everyoneGroup); groups.unshift(everyoneGroup);
let addGroup = {
id: 'addgroup',
key: 'addgroup',
icon: 'icon-add',
text: t('settings', 'Add group'),
classes: this.loadingAddGroup ? 'icon-loading-small' : ''
};
if (this.showAddGroupEntry) {
Vue.set(addGroup, 'edit', {
text: t('settings', 'Add group'),
action: this.createGroup,
reset: function() {
self.showAddGroupEntry = false
}
});
addGroup.classes = 'editing';
} else {
Vue.set(addGroup, 'action', function() {
self.showAddGroupEntry = true
})
}
groups.unshift(addGroup);
// Return // Return
return { return {
id: 'usergrouplist', id: 'usergrouplist',

View File

@ -13,14 +13,13 @@ module.exports = {
{ {
test: /\.css$/, test: /\.css$/,
use: [ use: [
'css-loader' 'vue-style-loader', 'css-loader'
], ],
}, },
{ {
test: /\.scss$/, test: /\.scss$/,
use: [ use: [
'css-loader', 'vue-style-loader', 'css-loader', 'sass-loader'
'sass-loader'
], ],
}, },
{ {