Revert "Fix table view"

This reverts commit cb852ef6

Signed-off-by: julia.kirschenheuter <julia.kirschenheuter@nextcloud.com>
This commit is contained in:
julia.kirschenheuter 2023-06-13 15:12:38 +02:00
parent 34c98566df
commit 83f2cc2f05
11 changed files with 190 additions and 206 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1417,8 +1417,14 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
.userActions {
display: flex;
justify-content: flex-end;
position: sticky;
right: 0px;
min-width: 88px;
background-color: var(--color-main-background);
}
&.row--editable .userActions {
z-index: 10;
}
.subtitle {
@ -1462,6 +1468,10 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
}
&:hover {
input:not([type='submit']):not(:focus):not(:active) {
border-color: var(--color-border) !important;
}
&:not(#grid-header) {
box-shadow: 5px 0 0 var(--color-primary-element) inset;
}
@ -1471,7 +1481,8 @@ doesnotexist:-o-prefocus, .strengthify-wrapper {
width: 100%;
}
> td,
> div,
> .displayName > form,
> form {
grid-row: 1;
display: inline-flex;

View file

@ -21,7 +21,7 @@
-->
<template>
<table id="app-content"
<div id="app-content"
role="grid"
:aria-label="t('settings', 'User\'s table')"
class="user-list-grid"
@ -154,9 +154,9 @@
:options="possibleManagers"
:placeholder="t('settings', 'Select user manager')"
class="multiselect-vue"
@search-change="searchUserManager"
label="displayname"
track-by="id">
track-by="id"
@search-change="searchUserManager">
<span slot="noResult">{{ t('settings', 'No results') }}</span>
</NcMultiselect>
</div>
@ -170,95 +170,89 @@
</div>
</form>
</NcModal>
<tbody>
<tr id="grid-header"
:class="{'sticky': scrolled && !showConfig.showNewUserForm}"
class="row">
<th id="headerAvatar" class="avatar">
<span class="hidden-visually"> {{ t('settings', 'Avatar') }} </span>
</th>
<th id="headerName" class="name">
<div class="subtitle">
<strong>
{{ t('settings', 'Display name') }}
</strong>
</div>
{{ t('settings', 'Username') }}
</th>
<th id="headerPassword" class="password">
{{ t('settings', 'Password') }}
</th>
<th id="headerAddress" class="mailAddress">
{{ t('settings', 'Email') }}
</th>
<th id="headerGroups" class="groups">
{{ t('settings', 'Groups') }}
</th>
<th v-if="subAdminsGroups.length>0 && settings.isAdmin"
id="headerSubAdmins"
class="subadmins">
{{ t('settings', 'Group admin for') }}
</th>
<th id="headerQuota" class="quota">
{{ t('settings', 'Quota') }}
</th>
<th v-if="showConfig.showLanguages"
id="headerLanguages"
class="languages">
{{ t('settings', 'Language') }}
</th>
<th v-if="showConfig.showUserBackend || showConfig.showStoragePath"
class="headerUserBackend userBackend">
<div v-if="showConfig.showUserBackend" class="userBackend">
{{ t('settings', 'User backend') }}
</div>
<div v-if="showConfig.showStoragePath"
class="subtitle storageLocation">
{{ t('settings', 'Storage location') }}
</div>
</th>
<th v-if="showConfig.showLastLogin"
class="headerLastLogin lastLogin">
{{ t('settings', 'Last login') }}
</th>
<th id="headerManager" class="manager">
{{ t('settings', 'Manager') }}
</th>
<th class="userActions hidden-visually">
{{ t('settings', 'User actions') }}
</th>
</tr>
<user-row v-for="user in filteredUsers"
:key="user.id"
:external-actions="externalActions"
:groups="groups"
:languages="languages"
:quota-options="quotaOptions"
:settings="settings"
:show-config="showConfig"
:sub-admins-groups="subAdminsGroups"
:user="user"
:users="users"
:is-dark-theme="isDarkTheme" />
<InfiniteLoading ref="infiniteLoading" @infinite="infiniteHandler">
<div slot="spinner">
<div class="users-icon-loading icon-loading" />
<div id="grid-header"
:class="{'sticky': scrolled && !showConfig.showNewUserForm}"
class="row">
<div id="headerAvatar" class="avatar" />
<div id="headerName" class="name">
<div class="subtitle">
<strong>
{{ t('settings', 'Display name') }}
</strong>
</div>
<div slot="no-more">
<div class="users-list-end" />
{{ t('settings', 'Username') }}
</div>
<div id="headerPassword" class="password">
{{ t('settings', 'Password') }}
</div>
<div id="headerAddress" class="mailAddress">
{{ t('settings', 'Email') }}
</div>
<div id="headerGroups" class="groups">
{{ t('settings', 'Groups') }}
</div>
<div v-if="subAdminsGroups.length>0 && settings.isAdmin"
id="headerSubAdmins"
class="subadmins">
{{ t('settings', 'Group admin for') }}
</div>
<div id="headerQuota" class="quota">
{{ t('settings', 'Quota') }}
</div>
<div v-if="showConfig.showLanguages"
id="headerLanguages"
class="languages">
{{ t('settings', 'Language') }}
</div>
<div v-if="showConfig.showUserBackend || showConfig.showStoragePath"
class="headerUserBackend userBackend">
<div v-if="showConfig.showUserBackend" class="userBackend">
{{ t('settings', 'User backend') }}
</div>
<div slot="no-results">
<div id="emptycontent">
<div class="icon-contacts-dark" />
<h2>{{ t('settings', 'No users in here') }}</h2>
</div>
<div v-if="showConfig.showStoragePath"
class="subtitle storageLocation">
{{ t('settings', 'Storage location') }}
</div>
</InfiniteLoading>
</tbody>
</table>
</div>
<div v-if="showConfig.showLastLogin"
class="headerLastLogin lastLogin">
{{ t('settings', 'Last login') }}
</div>
<div id="headerManager" class="manager">
{{ t('settings', 'Manager') }}
</div>
<div class="userActions" />
</div>
<user-row v-for="user in filteredUsers"
:key="user.id"
:external-actions="externalActions"
:groups="groups"
:languages="languages"
:quota-options="quotaOptions"
:settings="settings"
:show-config="showConfig"
:sub-admins-groups="subAdminsGroups"
:user="user"
:users="users"
:is-dark-theme="isDarkTheme" />
<InfiniteLoading ref="infiniteLoading" @infinite="infiniteHandler">
<div slot="spinner">
<div class="users-icon-loading icon-loading" />
</div>
<div slot="no-more">
<div class="users-list-end" />
</div>
<div slot="no-results">
<div id="emptycontent">
<div class="icon-contacts-dark" />
<h2>{{ t('settings', 'No users in here') }}</h2>
</div>
</div>
</InfiniteLoading>
</div>
</template>
<script>
@ -685,12 +679,4 @@ export default {
* prevent it). */
width: 0;
}
#app-content tbody tr {
&:hover,
&:focus,
&:active {
background-color: var(--color-main-background);
}
}
</style>

View file

@ -56,23 +56,23 @@
:user="user"
:is-dark-theme="isDarkTheme"
:class="{'row--menu-opened': openedMenu}" />
<tr v-else
<div v-else
:class="{
'disabled': loading.delete || loading.disable,
'row--menu-opened': openedMenu
}"
:data-id="user.id"
class="row row--editable">
<td :class="{'icon-loading-small': loading.delete || loading.disable || loading.wipe}"
<div :class="{'icon-loading-small': loading.delete || loading.disable || loading.wipe}"
class="avatar">
<img v-if="!loading.delete && !loading.disable && !loading.wipe"
:src="generateAvatar(user.id, isDarkTheme)"
alt=""
height="32"
width="32">
</td>
</div>
<!-- dirty hack to ellipsis on two lines -->
<td v-if="user.backendCapabilities.setDisplayName" class="displayName">
<div v-if="user.backendCapabilities.setDisplayName" class="displayName">
<form :class="{'icon-loading-small': loading.displayName}"
class="displayName"
@submit.prevent="updateDisplayName">
@ -90,56 +90,53 @@
type="submit"
value="">
</form>
</td>
<td v-else class="name">
</div>
<div v-else class="name">
{{ user.id }}
<div class="displayName subtitle">
<div :title="user.displayname.length > 20 ? user.displayname : ''" class="cellText">
{{ user.displayname }}
</div>
</div>
</td>
<td v-if="settings.canChangePassword && user.backendCapabilities.setPassword">
<form :class="{'icon-loading-small': loading.password}"
class="password"
@submit.prevent="updatePassword">
<label class="hidden-visually" :for="'password'+user.id+rand">{{ t('settings', 'Add new password') }}</label>
<input :id="'password'+user.id+rand"
ref="password"
:disabled="loading.password || loading.all"
:minlength="minPasswordLength"
maxlength="469"
:placeholder="t('settings', 'Add new password')"
autocapitalize="off"
autocomplete="new-password"
autocorrect="off"
required
spellcheck="false"
type="password"
value="">
<input class="icon-confirm" type="submit" value="">
</form>
</td>
<td v-else />
<td>
<form :class="{'icon-loading-small': loading.mailAddress}"
class="mailAddress"
@submit.prevent="updateEmail">
<label class="hidden-visually" :for="'mailAddress'+user.id+rand">{{ t('settings', 'Add new email address') }}</label>
<input :id="'mailAddress'+user.id+rand"
ref="mailAddress"
:disabled="loading.mailAddress||loading.all"
:placeholder="t('settings', 'Add new email address')"
:value="user.email"
autocapitalize="off"
autocomplete="new-password"
autocorrect="off"
spellcheck="false"
type="email">
<input class="icon-confirm" type="submit" value="">
</form>
</td>
<td :class="{'icon-loading-small': loading.groups}" class="groups">
</div>
<form v-if="settings.canChangePassword && user.backendCapabilities.setPassword"
:class="{'icon-loading-small': loading.password}"
class="password"
@submit.prevent="updatePassword">
<label class="hidden-visually" :for="'password'+user.id+rand">{{ t('settings', 'Add new password') }}</label>
<input :id="'password'+user.id+rand"
ref="password"
:disabled="loading.password || loading.all"
:minlength="minPasswordLength"
maxlength="469"
:placeholder="t('settings', 'Add new password')"
autocapitalize="off"
autocomplete="new-password"
autocorrect="off"
required
spellcheck="false"
type="password"
value="">
<input class="icon-confirm" type="submit" value="">
</form>
<div v-else />
<form :class="{'icon-loading-small': loading.mailAddress}"
class="mailAddress"
@submit.prevent="updateEmail">
<label class="hidden-visually" :for="'mailAddress'+user.id+rand">{{ t('settings', 'Add new email address') }}</label>
<input :id="'mailAddress'+user.id+rand"
ref="mailAddress"
:disabled="loading.mailAddress||loading.all"
:placeholder="t('settings', 'Add new email address')"
:value="user.email"
autocapitalize="off"
autocomplete="new-password"
autocorrect="off"
spellcheck="false"
type="email">
<input class="icon-confirm" type="submit" value="">
</form>
<div :class="{'icon-loading-small': loading.groups}" class="groups">
<label class="hidden-visually" :for="'groups'+user.id+rand">{{ t('settings', 'Add user to group') }}</label>
<NcMultiselect :id="'groups'+user.id+rand"
:close-on-select="false"
@ -160,8 +157,8 @@
@tag="createGroup">
<span slot="noResult">{{ t('settings', 'No results') }}</span>
</NcMultiselect>
</td>
<td v-if="subAdminsGroups.length>0 && settings.isAdmin"
</div>
<div v-if="subAdminsGroups.length>0 && settings.isAdmin"
:class="{'icon-loading-small': loading.subadmins}"
class="subadmins">
<label class="hidden-visually" :for="'subadmins'+user.id+rand">{{ t('settings', 'Set user as admin for') }}</label>
@ -181,8 +178,8 @@
@select="addUserSubAdmin">
<span slot="noResult">{{ t('settings', 'No results') }}</span>
</NcMultiselect>
</td>
<td :title="usedSpace"
</div>
<div :title="usedSpace"
:class="{'icon-loading-small': loading.quota}"
class="quota">
<label class="hidden-visually" :for="'quota'+user.id+rand">{{ t('settings', 'Select user quota') }}</label>
@ -199,8 +196,8 @@
track-by="id"
@input="setUserQuota"
@tag="validateQuota" />
</td>
<td v-if="showConfig.showLanguages"
</div>
<div v-if="showConfig.showLanguages"
:class="{'icon-loading-small': loading.languages}"
class="languages">
<label class="hidden-visually" :for="'language'+user.id+rand">{{ t('settings', 'Set the language') }}</label>
@ -216,8 +213,8 @@
label="name"
track-by="code"
@input="setUserLanguage" />
</td>
<td :class="{'icon-loading-small': loading.manager}" class="managers">
</div>
<div :class="{'icon-loading-small': loading.manager}" class="managers">
<NcMultiselect ref="manager"
v-model="currentManager"
:close-on-select="true"
@ -232,14 +229,14 @@
@select="updateUserManager">
<span slot="noResult">{{ t('settings', 'No results') }}</span>
</NcMultiselect>
</td>
</div>
<!-- don't show this on edit mode -->
<td v-if="showConfig.showStoragePath || showConfig.showUserBackend"
<div v-if="showConfig.showStoragePath || showConfig.showUserBackend"
class="storageLocation" />
<td v-if="showConfig.showLastLogin" />
<div v-if="showConfig.showLastLogin" />
<td class="userActions">
<div class="userActions">
<div v-if="!loading.all"
class="toggleUserActions">
<NcActions>
@ -263,8 +260,8 @@
<div class="icon-checkmark" />
{{ feedbackMessage }}
</div>
</td>
</tr>
</div>
</div>
</template>
<script>
@ -760,11 +757,4 @@ export default {
.row::v-deep .multiselect__single {
z-index: auto !important;
}
.displayName input,
.password input,
.mailAddress input {
width: 100%;
height: 44px!important;
border: 2px solid var(--color-border-dark);
}
</style>

View file

@ -1,16 +1,16 @@
<template>
<tr class="row"
<div class="row"
:class="{'disabled': loading.delete || loading.disable}"
:data-id="user.id">
<td class="avatar" :class="{'icon-loading-small': loading.delete || loading.disable || loading.wipe}">
<div class="avatar" :class="{'icon-loading-small': loading.delete || loading.disable || loading.wipe}">
<img v-if="!loading.delete && !loading.disable && !loading.wipe"
alt=""
width="32"
height="32"
:src="generateAvatar(user.id, isDarkTheme)">
</td>
</div>
<!-- dirty hack to ellipsis on two lines -->
<td class="name">
<div class="name">
<div class="displayName subtitle">
<div :title="user.displayname.length > 20 ? user.displayname : ''" class="cellText">
<strong>
@ -19,20 +19,20 @@
</div>
</div>
{{ user.id }}
</td>
<td />
<td class="mailAddress">
</div>
<div />
<div class="mailAddress">
<div :title="user.email !== null && user.email.length > 20 ? user.email : ''" class="cellText">
{{ user.email }}
</div>
</td>
<td class="groups">
</div>
<div class="groups">
{{ userGroupsLabels }}
</td>
<td v-if="subAdminsGroups.length > 0 && settings.isAdmin" class="subAdminsGroups">
</div>
<div v-if="subAdminsGroups.length > 0 && settings.isAdmin" class="subAdminsGroups">
{{ userSubAdminsGroupsLabels }}
</td>
<td class="userQuota">
</div>
<div class="userQuota">
<div class="quota">
{{ userQuota }} ({{ usedSpace }})
<progress class="quota-user-progress"
@ -40,25 +40,25 @@
:value="usedQuota"
max="100" />
</div>
</td>
<td v-if="showConfig.showLanguages" class="languages">
</div>
<div v-if="showConfig.showLanguages" class="languages">
{{ userLanguage.name }}
</td>
<td v-if="showConfig.showUserBackend || showConfig.showStoragePath" class="userBackend">
</div>
<div v-if="showConfig.showUserBackend || showConfig.showStoragePath" class="userBackend">
<div v-if="showConfig.showUserBackend" class="userBackend">
{{ user.backend }}
</div>
<div v-if="showConfig.showStoragePath" :title="user.storageLocation" class="storageLocation subtitle">
{{ user.storageLocation }}
</div>
</td>
<td v-if="showConfig.showLastLogin" :title="userLastLoginTooltip" class="lastLogin">
</div>
<div v-if="showConfig.showLastLogin" :title="userLastLoginTooltip" class="lastLogin">
{{ userLastLogin }}
</td>
<td class="managers">
</div>
<div class="managers">
{{ user.manager }}
</td>
<td class="userActions">
</div>
<div class="userActions">
<div v-if="canEdit && !loading.all" class="toggleUserActions">
<NcActions>
<NcActionButton icon="icon-rename"
@ -81,8 +81,8 @@
<div class="icon-checkmark" />
{{ feedbackMessage }}
</div>
</td>
</tr>
</div>
</div>
</template>
<script>
@ -205,7 +205,4 @@ export default {
background-color: var(--color-main-background);
border: 0;
}
.row .name {
padding-left: 0px!important;
}
</style>

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 one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -82,7 +82,7 @@ class UsersSettingsContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function rowForUser($user) {
return Locator::forThe()->css("table.user-list-grid tr.row[data-id=$user]")->
return Locator::forThe()->css("div.user-list-grid div.row[data-id=$user]")->
describedAs("Row for user $user in Users Settings");
}
@ -144,7 +144,7 @@ class UsersSettingsContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function theColumn($column) {
return Locator::forThe()->xpath("//table[@class='user-list-grid']//*[normalize-space() = '$column']")->
return Locator::forThe()->xpath("//div[@class='user-list-grid']//div[normalize-space() = '$column']")->
describedAs("The $column column in Users Settings");
}
@ -170,7 +170,7 @@ class UsersSettingsContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function editModeOn($user) {
return Locator::forThe()->css("table.user-list-grid tr.row.row--editable[data-id=$user]")->
return Locator::forThe()->css("div.user-list-grid div.row.row--editable[data-id=$user]")->
describedAs("I see the edit mode is on for the user $user in Users Settings");
}