Bump webpack, config, deps, fixes groups selects, improved design and added tooltip to groups +x indicator

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ (skjnldsv) 2018-05-18 16:39:34 +02:00
parent 746f3c9053
commit 38b1020f52
No known key found for this signature in database
GPG Key ID: 60C25B8C072916CF
11 changed files with 3529 additions and 1024 deletions

View File

@ -626,8 +626,8 @@ input {
margin: 1px 2px; margin: 1px 2px;
padding: 0 !important; padding: 0 !important;
display: inline-block; display: inline-block;
min-width: 160px; /* min-width: 160px; */
width: 160px; /* width: 160px; */
position: relative; position: relative;
background-color: $color-main-background; background-color: $color-main-background;
&.multiselect--active { &.multiselect--active {
@ -642,6 +642,9 @@ input {
background-color: nc-darken($color-main-background, 8%) !important; background-color: nc-darken($color-main-background, 8%) !important;
} }
.multiselect__tags { .multiselect__tags {
/* space between tags and limit tag */
$space-between: 5px;
display: flex; display: flex;
flex-wrap: nowrap; flex-wrap: nowrap;
overflow: hidden; overflow: hidden;
@ -657,7 +660,8 @@ input {
overflow: hidden; overflow: hidden;
max-width: 100%; max-width: 100%;
position: relative; position: relative;
padding: 3px 5px; padding: 3px $space-between;
flex-grow: 1;
/* no tags or simple select? Show input directly /* no tags or simple select? Show input directly
input is used to display single value */ input is used to display single value */
&:empty ~ input.multiselect__input { &:empty ~ input.multiselect__input {
@ -669,7 +673,7 @@ input {
} }
/* selected tag */ /* selected tag */
.multiselect__tag { .multiselect__tag {
flex: 0 0 auto; flex: 1 0 calc(50% - 5px);;
line-height: 20px; line-height: 20px;
padding: 1px 5px; padding: 1px 5px;
background-image: none; background-image: none;
@ -677,8 +681,25 @@ input {
border: 1px solid nc-darken($color-main-background, 14%); border: 1px solid nc-darken($color-main-background, 14%);
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
border-radius: 3px; border-radius: 3px;
margin-right: 5px; /* require to override the default width
and force the tag to shring properly */
min-width: 0;
/* css hack, detect if more than two tags
if so, flex-basis is set to half */
&:only-child {
flex: 0 1 auto;
}
&:not(:last-child) {
margin-right: $space-between;
}
/* ellipsis the groups to be sure
we display at least two of them */
> span {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
} }
} }
/* Single select default value */ /* Single select default value */
@ -690,13 +711,17 @@ input {
cursor: pointer; cursor: pointer;
} }
/* displayed text if tag limit reached */ /* displayed text if tag limit reached */
.multiselect__strong { .multiselect__strong,
.multiselect__limit {
flex: 0 0 auto; flex: 0 0 auto;
line-height: 20px; line-height: 20px;
color: nc-lighten($color-main-text, 33%); color: nc-lighten($color-main-text, 33%);
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
opacity: .7; opacity: .7;
margin-right: $space-between;
/* above the input */
z-index: 5;
} }
/* default multiselect input for search and placeholder */ /* default multiselect input for search and placeholder */
input.multiselect__input { input.multiselect__input {

View File

@ -75,8 +75,9 @@ ul.multiselectoptions {
} }
} }
div.multiselect, /* TODO drop old legacy multiselect! */
select.multiselect { div.multiselect:not(.multiselect-vue),
select.multiselect:not(.multiselect-vue) {
display: inline-block; display: inline-block;
max-width: 200px; max-width: 200px;
min-width: 150px !important; min-width: 150px !important;

View File

@ -1299,19 +1299,16 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
.password { .password {
width: 150px; width: 150px;
} }
.mailAddress{ .mailAddress,
.groups,
.subadmins {
width: 200px; width: 200px;
} }
.groups,
.subadmins,
.quota { .quota {
width: 170px; width: 150px;
} }
.languages { .languages {
width: 200px; width: 200px;
.multiselect {
width: 100%;
}
} }
.storageLocation { .storageLocation {
width: 250px; width: 250px;
@ -1379,7 +1376,7 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
} }
progress { progress {
position: absolute; position: absolute;
width: 160px; width: calc(100% - 4px); /* minus left and right */
left: 2px; left: 2px;
bottom: 2px; bottom: 2px;
height: 3px; height: 3px;
@ -1415,24 +1412,9 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
} }
} }
} }
.v-select { /* Fill the grid cell */
&.open .selected-tag-wrap { .multiselect.multiselect-vue {
display: none; width: 100%;
}
.dropdown-toggle .selected-tag {
padding-right: 5px;
.close {
/* no delete on tags*/
display: none;
}
}
.dropdown-menu li a .icon-add {
position: absolute;
width: 16px;
height: 16px;
opacity: .5;
left: 7px;
}
} }
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -6,17 +6,17 @@
"license": "AGPL3", "license": "AGPL3",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "cross-env NODE_ENV=development webpack", "dev": "webpack --config webpack.dev.js",
"watch": "cross-env NODE_ENV=development webpack --progress --watch", "watch": "webpack --progress --watch --config webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules" "build": "webpack --progress --hide-modules --config webpack.prod.js"
}, },
"dependencies": { "dependencies": {
"axios": "^0.18.0", "axios": "^0.18.0",
"babel-polyfill": "^6.26.0", "babel-polyfill": "^6.26.0",
"v-tooltip": "^2.0.0-rc.31", "v-tooltip": "^2.0.0-rc.32",
"vue": "^2.5.11", "vue": "^2.5.16",
"vue-click-outside": "^1.0.7", "vue-click-outside": "^1.0.7",
"vue-infinite-loading": "^2.2.3", "vue-infinite-loading": "^2.3.1",
"vue-localstorage": "^0.6.2", "vue-localstorage": "^0.6.2",
"vue-multiselect": "^2.1.0", "vue-multiselect": "^2.1.0",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
@ -28,17 +28,18 @@
"ie >= 11" "ie >= 11"
], ],
"devDependencies": { "devDependencies": {
"babel-core": "^6.26.0", "babel-core": "^6.26.3",
"babel-loader": "^7.1.2", "babel-loader": "^7.1.4",
"babel-preset-env": "^1.6.0", "babel-preset-env": "^1.7.0",
"babel-preset-stage-3": "^6.24.1", "babel-preset-stage-3": "^6.24.1",
"cross-env": "^5.0.5", "css-loader": "^0.28.11",
"css-loader": "^0.28.7", "file-loader": "^1.1.11",
"file-loader": "^1.1.4", "node-sass": "^4.9.0",
"node-sass": "^4.5.3", "sass-loader": "^7.0.1",
"sass-loader": "^6.0.6", "vue-loader": "^14.2.2",
"vue-loader": "^13.0.5", "vue-template-compiler": "^2.5.16",
"vue-template-compiler": "^2.4.4", "webpack": "^4.8.3",
"webpack": "^3.6.0" "webpack-cli": "^2.1.3",
"webpack-merge": "^4.1.2"
} }
} }

View File

@ -32,20 +32,20 @@
<div class="groups" :class="{'icon-loading-small': loading.groups}"> <div class="groups" :class="{'icon-loading-small': loading.groups}">
<multiselect :value="userGroups" :options="groups" :disabled="loading.groups||loading.all" <multiselect :value="userGroups" :options="groups" :disabled="loading.groups||loading.all"
tag-placeholder="create" :placeholder="t('settings', 'Add user in group')" tag-placeholder="create" :placeholder="t('settings', 'Add user in group')"
label="name" track-by="id" class="multiselect-vue" label="name" track-by="id" class="multiselect-vue" :limit="2"
:limit="2" :limitText="limitGroups"
:multiple="true" :taggable="settings.isAdmin" :closeOnSelect="false" :multiple="true" :taggable="settings.isAdmin" :closeOnSelect="false"
@tag="createGroup" @select="addUserGroup" @remove="removeUserGroup"> @tag="createGroup" @select="addUserGroup" @remove="removeUserGroup">
<span slot="limit" class="multiselect__limit" v-tooltip.auto="formatGroupsTitle(userGroups)">+{{userGroups.length-2}}</span>
<span slot="noResult">{{t('settings', 'No results')}}</span> <span slot="noResult">{{t('settings', 'No results')}}</span>
</multiselect> </multiselect>
</div> </div>
<div class="subadmins" v-if="subAdminsGroups.length>0 && settings.isAdmin" :class="{'icon-loading-small': loading.subadmins}"> <div class="subadmins" v-if="subAdminsGroups.length>0 && settings.isAdmin" :class="{'icon-loading-small': loading.subadmins}">
<multiselect :value="userSubAdminsGroups" :options="subAdminsGroups" :disabled="loading.subadmins||loading.all" <multiselect :value="userSubAdminsGroups" :options="subAdminsGroups" :disabled="loading.subadmins||loading.all"
:placeholder="t('settings', 'Set user as admin for')" :placeholder="t('settings', 'Set user as admin for')"
label="name" track-by="id" class="multiselect-vue" label="name" track-by="id" class="multiselect-vue" :limit="2"
:limit="2" :limitText="limitGroups"
:multiple="true" :closeOnSelect="false" :multiple="true" :closeOnSelect="false"
@select="addUserSubAdmin" @remove="removeUserSubAdmin"> @select="addUserSubAdmin" @remove="removeUserSubAdmin">
<span slot="limit" class="multiselect__limit" v-tooltip.auto="formatGroupsTitle(userSubAdminsGroups)">+{{userSubAdminsGroups.length-2}}</span>
<span slot="noResult">{{t('settings', 'No results')}}</span> <span slot="noResult">{{t('settings', 'No results')}}</span>
</multiselect> </multiselect>
</div> </div>
@ -222,15 +222,14 @@ export default {
); );
}, },
/** /**
* Format the limit text in the selected options * Format array of groups objects to a string for the popup
* *
* @param {int} count elements left * @param {array} groups The groups
* @returns {string} * @returns {string}
*/ */
limitGroups(count) { formatGroupsTitle(groups) {
return '+'+count; return groups.map(group => group.name).join(', ');
}, },
deleteUser() { deleteUser() {

View File

@ -1,12 +1,11 @@
var path = require('path') const path = require('path')
var webpack = require('webpack')
module.exports = { module.exports = {
entry: './src/main.js', entry: './src/main.js',
output: { output: {
path: path.resolve(__dirname, './js'), path: path.resolve(__dirname, './dist'),
publicPath: '/dist/', publicPath: '/dist/',
filename: 'main.js' filename: 'build.js'
}, },
module: { module: {
rules: [ rules: [
@ -74,35 +73,5 @@ module.exports = {
'vue$': 'vue/dist/vue.esm.js' 'vue$': 'vue/dist/vue.esm.js'
}, },
extensions: ['*', '.js', '.vue', '.json'] extensions: ['*', '.js', '.vue', '.json']
}, }
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
performance: {
hints: false
},
devtool: '#eval-source-map'
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
// http://vue-loader.vuejs.org/en/workflow/production.html
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
} }

12
settings/webpack.dev.js Normal file
View File

@ -0,0 +1,12 @@
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devServer: {
historyApiFallback: true,
noInfo: true,
overlay: true
},
devtool: '#eval-source-map',
})

7
settings/webpack.prod.js Normal file
View File

@ -0,0 +1,7 @@
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
module.exports = merge(common, {
mode: 'production',
devtool: '#source-map'
})