Skip to content

Commit 412f03f

Browse files
committed
feat(policy): use app navigation search for rule toolbar
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 29c972b commit 412f03f

1 file changed

Lines changed: 61 additions & 105 deletions

File tree

src/views/Settings/PolicyWorkbench/RealPolicyWorkbench.vue

Lines changed: 61 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -176,65 +176,56 @@
176176
</div>
177177

178178
<div class="policy-workbench__table-toolbar-row policy-workbench__table-toolbar-row--crud">
179-
<NcTextField
179+
<NcAppNavigationSearch
180180
:model-value="crudSearch"
181181
:label="t('libresign', 'Search rules')"
182182
:placeholder="t('libresign', 'Search by scope, target, or value')"
183-
@update:modelValue="onCrudSearchChange" />
184-
185-
<div class="policy-workbench__crud-controls">
186-
<NcPopover :boundary="popoverBoundary">
187-
<template #trigger>
188-
<NcButton :aria-label="t('libresign', 'Filters')" :pressed="crudScopeFilter !== 'all'" variant="tertiary">
189-
<template #icon>
190-
<NcIconSvgWrapper :path="mdiFilterVariant" />
191-
</template>
192-
{{ t('libresign', 'Filters') }}
193-
</NcButton>
194-
</template>
195-
<template #default>
196-
<div class="policy-workbench__crud-filter-popover">
197-
<p class="policy-workbench__crud-filter-title">{{ t('libresign', 'Scope') }}</p>
198-
<div class="policy-workbench__crud-filter-options">
199-
<label class="policy-workbench__filter-option">
200-
<input type="radio" name="crudScope" :checked="crudScopeFilter === 'all'" @change="setCrudScopeFilter('all', true)" />
201-
<span>{{ t('libresign', 'All scopes') }}</span>
202-
</label>
203-
<label class="policy-workbench__filter-option">
204-
<input type="radio" name="crudScope" :checked="crudScopeFilter === 'system'" @change="setCrudScopeFilter('system', true)" />
205-
<span>{{ t('libresign', 'Instance') }}</span>
206-
</label>
207-
<label class="policy-workbench__filter-option">
208-
<input type="radio" name="crudScope" :checked="crudScopeFilter === 'group'" @change="setCrudScopeFilter('group', true)" />
209-
<span>{{ t('libresign', 'Group') }}</span>
210-
</label>
211-
<label class="policy-workbench__filter-option">
212-
<input type="radio" name="crudScope" :checked="crudScopeFilter === 'user'" @change="setCrudScopeFilter('user', true)" />
213-
<span>{{ t('libresign', 'User') }}</span>
214-
</label>
215-
</div>
216-
<NcButton v-if="crudScopeFilter !== 'all'" variant="tertiary" @click="setCrudScopeFilter('all', true)">
217-
{{ t('libresign', 'Clear filter') }}
218-
</NcButton>
219-
</div>
220-
</template>
221-
</NcPopover>
222-
223-
<div v-if="activeScopeFilterChip" class="policy-workbench__crud-filter-chips">
224-
<NcChip :aria-label-close="t('libresign', 'Remove filter')" :text="activeScopeFilterChip" @close="setCrudScopeFilter('all', true)" />
225-
</div>
226-
</div>
227-
228-
<div v-if="state.viewMode === 'system-admin'" class="policy-workbench__crud-create">
229-
<NcButton variant="primary" size="small" :disabled="!hasCreatableScope" :title="createRuleDisabledReason || undefined" @click="requestCreateRule()">
230-
{{ t('libresign', 'Create rule') }}
231-
</NcButton>
232-
<p v-if="createRuleDisabledReason" class="policy-workbench__table-note policy-workbench__table-note--align-right">
233-
{{ createRuleDisabledReason }}
234-
</p>
183+
@update:modelValue="onCrudSearchChange">
184+
<template #actions>
185+
<NcActions :aria-label="t('libresign', 'Filter rules by scope')">
186+
<template #icon>
187+
<NcIconSvgWrapper :path="mdiFilterVariant" :size="20" />
188+
</template>
189+
<NcActionButton @click="setCrudScopeFilter('all', true)">
190+
{{ t('libresign', 'All scopes') }}
191+
</NcActionButton>
192+
<NcActionButton @click="setCrudScopeFilter('system', true)">
193+
{{ t('libresign', 'Instance') }}
194+
</NcActionButton>
195+
<NcActionButton @click="setCrudScopeFilter('group', true)">
196+
{{ t('libresign', 'Group') }}
197+
</NcActionButton>
198+
<NcActionButton @click="setCrudScopeFilter('user', true)">
199+
{{ t('libresign', 'User') }}
200+
</NcActionButton>
201+
</NcActions>
202+
203+
<NcButton
204+
v-if="state.viewMode === 'system-admin'"
205+
variant="tertiary"
206+
size="small"
207+
:disabled="!hasCreatableScope"
208+
:title="createRuleDisabledReason || undefined"
209+
:aria-label="t('libresign', 'Create rule')"
210+
class="policy-workbench__crud-create-button"
211+
@click="requestCreateRule()">
212+
<template #icon>
213+
<NcIconSvgWrapper :path="mdiPlus" :size="20" />
214+
</template>
215+
{{ t('libresign', 'Create rule') }}
216+
</NcButton>
217+
</template>
218+
</NcAppNavigationSearch>
219+
220+
<div v-if="activeScopeFilterChip" class="policy-workbench__crud-filter-chips">
221+
<NcChip :aria-label-close="t('libresign', 'Remove filter')" :text="activeScopeFilterChip" @close="setCrudScopeFilter('all', true)" />
235222
</div>
236223
</div>
237224

225+
<p v-if="createRuleDisabledReason && state.viewMode === 'system-admin'" class="policy-workbench__table-note policy-workbench__table-note--align-right">
226+
{{ createRuleDisabledReason }}
227+
</p>
228+
238229
<p v-if="state.createUserOverrideDisabledReason && crudScopeFilter === 'user'" class="policy-workbench__table-note">
239230
{{ t('libresign', 'Some users may not allow user overrides because their group rule requires inheritance.') }}
240231
</p>
@@ -411,19 +402,20 @@ import {
411402
mdiFilterVariant,
412403
mdiFormatListBulletedSquare,
413404
mdiPencil,
405+
mdiPlus,
414406
mdiViewGridOutline,
415407
} from '@mdi/js'
416408
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
417409
import { t } from '@nextcloud/l10n'
418410
419411
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
420412
import NcActions from '@nextcloud/vue/components/NcActions'
413+
import NcAppNavigationSearch from '@nextcloud/vue/components/NcAppNavigationSearch'
421414
import NcButton from '@nextcloud/vue/components/NcButton'
422415
import NcChip from '@nextcloud/vue/components/NcChip'
423416
import NcDialog from '@nextcloud/vue/components/NcDialog'
424417
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
425418
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard'
426-
import NcPopover from '@nextcloud/vue/components/NcPopover'
427419
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection'
428420
import NcTextField from '@nextcloud/vue/components/NcTextField'
429421
@@ -455,7 +447,6 @@ const recentSelectionGesture = ref<{ surface: 'cards' | 'list', key: string, at:
455447
const crudSearch = ref('')
456448
const crudScopeFilter = ref<'all' | 'system' | 'group' | 'user'>('all')
457449
const crudPage = ref(1)
458-
const popoverBoundary = document.getElementById('app-content-vue') ?? document.body
459450
const CRUD_PAGE_SIZE = 20
460451
461452
const DRAG_OPEN_THRESHOLD_PX = 6
@@ -1067,32 +1058,10 @@ onBeforeUnmount(() => {
10671058
color: var(--color-text-maxcontrast);
10681059
}
10691060
1070-
&__crud-filter-popover {
1071-
display: flex;
1072-
flex-direction: column;
1073-
gap: calc(var(--default-grid-baseline) / 2);
1074-
padding: calc(var(--default-grid-baseline) / 2);
1075-
min-width: calc(7 * var(--default-clickable-area));
1076-
}
1077-
1078-
&__crud-filter-title {
1079-
margin: 0;
1080-
font-size: 0.78rem;
1081-
font-weight: 600;
1082-
letter-spacing: 0.01em;
1083-
text-transform: uppercase;
1084-
color: var(--color-text-maxcontrast);
1085-
}
1086-
1087-
&__crud-filter-options {
1088-
display: flex;
1089-
flex-direction: column;
1090-
gap: 0.4rem;
1091-
}
1092-
10931061
&__crud-filter-chips {
10941062
display: flex;
10951063
align-items: center;
1064+
margin-left: auto;
10961065
}
10971066
10981067
&__settings-grid {
@@ -1460,26 +1429,23 @@ onBeforeUnmount(() => {
14601429
align-items: flex-end;
14611430
gap: 0.85rem;
14621431
1463-
:deep(.text-field) {
1464-
flex: 1 1 320px;
1465-
min-width: min(100%, 320px);
1432+
:deep(.app-navigation-search) {
1433+
flex: 1 1 420px;
1434+
min-width: min(100%, 420px);
14661435
}
1467-
}
1468-
}
14691436
1470-
&__crud-controls {
1471-
display: flex;
1472-
align-items: center;
1473-
gap: 0.5rem;
1474-
flex: 0 1 auto;
1437+
:deep(.app-navigation-search__actions) {
1438+
display: inline-flex;
1439+
align-items: center;
1440+
gap: 0.25rem;
1441+
}
1442+
}
14751443
}
14761444
1477-
&__crud-create {
1478-
display: flex;
1479-
flex-direction: column;
1480-
align-items: flex-end;
1481-
gap: 0.45rem;
1482-
margin-left: auto;
1445+
&__crud-create-button {
1446+
:deep(.button-vue) {
1447+
white-space: nowrap;
1448+
}
14831449
}
14841450
14851451
@@ -1560,20 +1526,10 @@ onBeforeUnmount(() => {
15601526
align-items: stretch;
15611527
}
15621528
1563-
&__crud-controls {
1529+
&__crud-filter-chips {
15641530
width: 100%;
15651531
justify-content: flex-start;
1566-
}
1567-
1568-
&__crud-create {
15691532
margin-left: 0;
1570-
align-items: stretch;
1571-
width: 100%;
1572-
1573-
:deep(.button-vue) {
1574-
width: 100%;
1575-
justify-content: center;
1576-
}
15771533
}
15781534
15791535
&__table-note--align-right {

0 commit comments

Comments
 (0)