Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create right table view #40014

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/settings/css/settings.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/settings/css/settings.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 1 addition & 9 deletions apps/settings/css/settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -842,10 +842,6 @@ span.version {
overflow: hidden;
}

.app-name, .app-version, .app-score, .app-level {
display: inline-block;
}

.app-description-toggle-show, .app-description-toggle-hide {
clear: both;
padding: 7px 0;
Expand Down Expand Up @@ -918,7 +914,6 @@ span.version {
display: table;
width: 100%;
height: auto;
margin-top: $toolbar-height;
}

margin-bottom: 100px;
Expand Down Expand Up @@ -1042,7 +1037,6 @@ span.version {

/* Bundle header */
.apps-header {
display: table-row;
position: relative;

div {
Expand All @@ -1051,11 +1045,9 @@ span.version {
}

h2 {
display: table-cell;
position: absolute;
padding-left: 6px;
padding-top: 15px;

margin-bottom: 12px;
.enable {
position: relative;
top: -1px;
Expand Down
86 changes: 68 additions & 18 deletions apps/settings/src/components/AppList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,71 @@
{{ t('settings', 'All apps are up-to-date.') }}
</div>

<transition-group name="app-list" tag="div" class="apps-list-container">
<transition-group name="app-list" tag="table" class="apps-list-container">
<tr key="app-list-view-header" class="apps-header">
<th class="app-image">
<span class="hidden-visually">{{ t('settings', 'Icon') }}</span>
</th>
<th class="app-name">
<span class="hidden-visually">{{ t('settings', 'Name') }}</span>
</th>
<th class="app-version">
<span class="hidden-visually">{{ t('settings', 'Version') }}</span>
</th>
<th class="app-level">
<span class="hidden-visually">{{ t('settings', 'Level') }}</span>
</th>
<th class="actions">
<span class="hidden-visually">{{ t('settings', 'Actions') }}</span>
</th>
</tr>
<AppItem v-for="app in apps"
:key="app.id"
:app="app"
:category="category" />
</transition-group>
</template>

<transition-group v-if="useBundleView"
name="app-list"
tag="div"
<table v-if="useBundleView"
class="apps-list-container">
<tr key="app-list-view-header" class="apps-header">
<th id="app-table-col-icon" class="app-image">
<span class="hidden-visually">{{ t('settings', 'Icon') }}</span>
</th>
<th id="app-table-col-name" class="app-name">
<span class="hidden-visually">{{ t('settings', 'Name') }}</span>
</th>
<th id="app-table-col-version" class="app-version">
<span class="hidden-visually">{{ t('settings', 'Version') }}</span>
</th>
<th id="app-table-col-level" class="app-level">
<span class="hidden-visually">{{ t('settings', 'Level') }}</span>
</th>
<th id="app-table-col-actions" class="actions">
<span class="hidden-visually">{{ t('settings', 'Actions') }}</span>
</th>
</tr>
<template v-for="bundle in bundles">
<div :key="bundle.id" class="apps-header">
<div class="app-image" />
<h2>{{ bundle.name }} <input type="button" :value="bundleToggleText(bundle.id)" @click="toggleBundle(bundle.id)"></h2>
<div class="app-version" />
<div class="app-level" />
<div class="app-groups" />
<div class="actions">
&nbsp;
</div>
</div>
<tr :key="bundle.id">
<th :id="`app-table-rowgroup-${bundle.id}`" colspan="5" scope="rowgroup">
<div class="app-bundle-heading">
<span class="app-bundle-header">
{{ bundle.name }}
</span>
<NcButton type="secondary" @click="toggleBundle(bundle.id)">
{{ t('settings', bundleToggleText(bundle.id)) }}
</NcButton>
</div>
</th>
</tr>
<AppItem v-for="app in bundleApps(bundle.id)"
:key="bundle.id + app.id"
:use-bundle-view="true"
:headers="`app-table-rowgroup-${bundle.id}`"
:app="app"
:category="category" />
</template>
</transition-group>
</table>
<template v-if="useAppStoreView">
<AppItem v-for="app in apps"
:key="app.id"
Expand All @@ -88,8 +124,7 @@
<AppItem v-for="app in searchApps"
:key="app.id"
:app="app"
:category="category"
:list-view="true" />
:category="category" />
</template>
</div>
</div>
Expand Down Expand Up @@ -240,9 +275,24 @@ export default {
const limit = pLimit(1)
this.apps
.filter(app => app.update)
.map(app => limit(() => this.$store.dispatch('updateApp', { appId: app.id }))
.map(app => limit(() => this.$store.dispatch('updateApp', { appId: app.id })),
)
},
},
}
</script>

<style lang="scss" scoped>
.app-bundle-heading {
display: flex;
align-items: center;
margin: 20px 10px 20px 0;
}
.app-bundle-header {
margin: 0 10px 0 50px;
font-weight: bold;
font-size: 20px;
line-height: 30px;
color: var(--color-text-light);
}
</style>
59 changes: 44 additions & 15 deletions apps/settings/src/components/AppList/AppItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@
-->

<template>
<div class="section" :class="{ selected: isSelected }" @click="showAppDetails">
<div class="app-image app-image-icon" @click="showAppDetails">
<component :is="listView ? `tr` : `div`"
class="section"
:class="{ selected: isSelected }"
@click="showAppDetails">
<component :is="dataItemTag"
class="app-image app-image-icon"
:headers="getDataItemHeaders(`app-table-col-icon`)"
@click="showAppDetails">
<div v-if="(listView && !app.preview) || (!listView && !screenshotLoaded)" class="icon-settings-dark" />

<svg v-else-if="listView && app.preview"
Expand All @@ -39,19 +45,28 @@
</svg>

<img v-if="!listView && app.screenshot && screenshotLoaded" :src="app.screenshot" width="100%">
</div>
<div class="app-name" @click="showAppDetails">
</component>
<component :is="dataItemTag"
class="app-name"
:headers="getDataItemHeaders(`app-table-col-name`)"
@click="showAppDetails">
{{ app.name }}
</div>
<div v-if="!listView" class="app-summary">
</component>
<component :is="dataItemTag"
v-if="!listView"
class="app-summary"
:headers="getDataItemHeaders(`app-version`)">
{{ app.summary }}
</div>
<div v-if="listView" class="app-version">
</component>
<component :is="dataItemTag"
v-if="listView"
class="app-version"
:headers="getDataItemHeaders(`app-table-col-version`)">
<span v-if="app.version">{{ app.version }}</span>
<span v-else-if="app.appstoreData.releases[0].version">{{ app.appstoreData.releases[0].version }}</span>
</div>
</component>

<div class="app-level">
<component :is="dataItemTag" :headers="getDataItemHeaders(`app-table-col-level`)" class="app-level">
<span v-if="app.level === 300"
:title="t('settings', 'This app is supported via your current Nextcloud subscription.')"
:aria-label="t('settings', 'This app is supported via your current Nextcloud subscription.')"
Expand All @@ -63,9 +78,8 @@
class="official icon-checkmark">
{{ t('settings', 'Featured') }}</span>
<AppScore v-if="hasRating && !listView" :score="app.score" />
</div>

<div class="actions">
</component>
<component :is="dataItemTag" :headers="getDataItemHeaders(`app-table-col-actions`)" class="actions">
<div v-if="app.error" class="warning">
{{ app.error }}
</div>
Expand Down Expand Up @@ -104,8 +118,8 @@
@click.stop="forceEnable(app.id)">
{{ forceEnableButtonText }}
</NcButton>
</div>
</div>
</component>
</component>
</template>

<script>
Expand All @@ -128,6 +142,14 @@ export default {
type: Boolean,
default: true,
},
useBundleView: {
type: Boolean,
default: false,
},
headers: {
type: String,
default: null,
},
},
data() {
return {
Expand All @@ -140,6 +162,9 @@ export default {
hasRating() {
return this.app.appstoreData && this.app.appstoreData.ratingNumOverall > 5
},
dataItemTag() {
return this.listView ? 'td' : 'div'
},
},
watch: {
'$route.params.id'(id) {
Expand Down Expand Up @@ -176,6 +201,10 @@ export default {
prefix(prefix, content) {
return prefix + '_' + content
},

getDataItemHeaders(columnName) {
return this.useBundleView ? [this.headers, columnName].join(' ') : null
},
},
}
</script>
Expand Down
4 changes: 2 additions & 2 deletions dist/settings-apps-view-7418.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-apps-view-7418.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-apps-users-management.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-apps-users-management.js.map

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions tests/acceptance/features/bootstrap/AppsManagementContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class AppsManagementContext implements Context, ActorAwareInterface {
* @return Locator
*/
public static function appsList() {
return Locator::forThe()->xpath("//main[@id='app-content' or contains(@class, 'app-content')]//div[@id='apps-list']")->
return Locator::forThe()->xpath("//main[@id='app-content' or contains(@class, 'app-content')]//*[@id='apps-list']")->
describedAs("Apps list in Apps Management");
}

Expand Down Expand Up @@ -86,7 +86,7 @@ public static function disableButtonForAnyApp() {
* @return Locator
*/
public static function enableAllBundleButton($bundle) {
return Locator::forThe()->xpath("//div[@class='apps-header']/h2[normalize-space() = '$bundle']/input[@value='Download and enable all']")->
return Locator::forThe()->xpath("//th[//*[normalize-space() = '$bundle']]//button[normalize-space() = 'Download and enable all']")->
descendantOf(self::appsList())->
describedAs("Button to enable bundles");
}
Expand All @@ -95,7 +95,7 @@ public static function enableAllBundleButton($bundle) {
* @return Locator
*/
public static function rowForApp($app) {
return Locator::forThe()->xpath("//div[@class='app-name'][normalize-space() = '$app']/..")->
return Locator::forThe()->xpath("//*[@class='app-name'][normalize-space() = '$app']/..")->
descendantOf(self::appsList())->
describedAs("Row for app $app in Apps Management");
}
Expand All @@ -104,7 +104,7 @@ public static function rowForApp($app) {
* @return Locator
*/
public static function emptyAppList() {
return Locator::forThe()->xpath("//div[@id='apps-list-empty']")->
return Locator::forThe()->xpath("//*[@id='apps-list-empty']")->
descendantOf(self::appsList())->
describedAs("Empty apps list view");
}
Expand Down
Loading