Skip to content
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
772 changes: 692 additions & 80 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@
"@types/jest": "^29.5.12",
"@types/node": "^20.14.12",
"@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-vue": "^6.0.8",
"@vitest/coverage-v8": "^3.2.7",
"@vue/compiler-dom": "^3.5.41",
"@vue/compiler-sfc": "^3.5.40",
"@vue/eslint-config-typescript": "^13.0.0",
"@vue/test-utils": "^2.4.6",
Expand All @@ -123,6 +125,7 @@
"jest": "^29.0.0",
"jest-environment-jsdom": "^29.7.0",
"jest-transform-stub": "^2.0.0",
"jsdom": "^29.1.1",
"postcss-html": "^1.8.1",
"stylelint": "^15.11.0",
"stylelint-config-recommended-scss": "^13.1.0",
Expand Down
33 changes: 20 additions & 13 deletions src/components/AlwaysVisibleSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,26 +81,36 @@
</div>
</div>

<!-- Info Modal -->
<NcModal
<!-- Info Modal — own file per ADR-004/ADR-012 -->
<AlwaysVisibleSectionInfoModal
v-if="hasInfoContent"
:name="name"
:show="showInfoModal"
:title="name + ' Information'"
:name="name + ' Info'"
@close="showInfoModal = false">
<div class="info-content">
<!--
BOTH slot names are honoured. `info-content` wins when supplied and
`info` is the fallback, so no caller can be silently empty.

This section only ever declared `info`, but four of its five callers
(UserGroupsConfiguration, EmailConfiguration, ArchiMateImportExport,
OrganizationSynchronization) pass `#info-content` — the name
CollapsibleSection uses. They all set `:has-info-content="true"`, so
the (i) button rendered and opened a completely EMPTY modal.
-->
<slot name="info-content">
<slot name="info" />
</div>
</NcModal>
</slot>
</AlwaysVisibleSectionInfoModal>
</NcSettingsSection>
</template>

<script>
import { defineComponent } from 'vue'
import { NcSettingsSection, NcButton, NcLoadingIcon, NcModal } from '@nextcloud/vue'
import { NcSettingsSection, NcButton, NcLoadingIcon } from '@nextcloud/vue'
import Save from 'vue-material-design-icons/ContentSave.vue'
import Refresh from 'vue-material-design-icons/Refresh.vue'
import Information from 'vue-material-design-icons/Information.vue'
import AlwaysVisibleSectionInfoModal from '../modals/AlwaysVisibleSectionInfoModal.vue'

/**
* Always Visible Section component
Expand All @@ -117,10 +127,10 @@
NcSettingsSection,
NcButton,
NcLoadingIcon,
NcModal,
Save,
Refresh,
Information,
AlwaysVisibleSectionInfoModal,
},

props: {
Expand Down Expand Up @@ -238,7 +248,7 @@
methods: {
/**
* Handle save button click
* @spec openspec/specs/fe-shell-navigation/spec.md

Check warning on line 251 in src/components/AlwaysVisibleSection.vue

View workflow job for this annotation

GitHub Actions / quality / Vue Quality (eslint)

Expected JSDoc block to be aligned
*/
handleSave() {
this.$emit('save')
Expand All @@ -246,7 +256,7 @@

/**
* Handle refresh button click
* @spec openspec/specs/fe-shell-navigation/spec.md

Check warning on line 259 in src/components/AlwaysVisibleSection.vue

View workflow job for this annotation

GitHub Actions / quality / Vue Quality (eslint)

Expected JSDoc block to be aligned
*/
handleRefresh() {
this.$emit('refresh')
Expand Down Expand Up @@ -311,10 +321,7 @@
color: var(--color-text-lighter);
}

.info-content {
max-width: 600px;
line-height: 1.6;
}
/* .info-content lives with the modal in src/modals/AlwaysVisibleSectionInfoModal.vue */

/* Responsive */
@media (max-width: 768px) {
Expand Down
107 changes: 20 additions & 87 deletions src/components/CollapsibleSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,26 +96,23 @@
</div>
</div>

<!-- Info Modal -->
<NcModal
<!-- Info Modal — own file per ADR-004/ADR-012 -->
<CollapsibleSectionInfoModal
v-if="showInfoModal"
:name="name"
@close="showInfoModal = false">
<div class="info-modal">
<div class="modal-header">
<h2>{{ name }} - Information</h2>
</div>
<div class="modal-content">
<slot name="info-content">
<p>No additional information available.</p>
</slot>
</div>
<div class="modal-footer">
<NcButton @click="showInfoModal = false">
Close
</NcButton>
</div>
</div>
</NcModal>
<!--
BOTH slot names are honoured, matching AlwaysVisibleSection: this
section has always used `info-content`, and `info` is accepted as an
alias so the two sections share one slot API and no caller can be
silently empty. The empty-state paragraph is the last fallback.
-->
<slot name="info-content">
<slot name="info">
<p>No additional information available.</p>
</slot>
</slot>
</CollapsibleSectionInfoModal>
</NcSettingsSection>
</template>

Expand All @@ -136,7 +133,6 @@
NcSettingsSection,
NcButton,
NcLoadingIcon,
NcModal,
} from '@nextcloud/vue'

// Icons
Expand All @@ -146,19 +142,21 @@
import ChevronUp from 'vue-material-design-icons/ChevronUp.vue'
import ChevronDown from 'vue-material-design-icons/ChevronDown.vue'

import CollapsibleSectionInfoModal from '../modals/CollapsibleSectionInfoModal.vue'

export default {
name: 'CollapsibleSection',

components: {
NcSettingsSection,
NcButton,
NcLoadingIcon,
NcModal,
Save,
Refresh,
Information,
ChevronUp,
ChevronDown,
CollapsibleSectionInfoModal,
},

props: {
Expand Down Expand Up @@ -279,7 +277,7 @@
methods: {
/**
* Toggle section expanded state
* @spec openspec/specs/fe-shell-navigation/spec.md

Check warning on line 280 in src/components/CollapsibleSection.vue

View workflow job for this annotation

GitHub Actions / quality / Vue Quality (eslint)

Expected JSDoc block to be aligned
*/
toggleExpanded() {
this.isExpanded = !this.isExpanded
Expand All @@ -287,7 +285,7 @@

/**
* Handle save button click
* @spec openspec/specs/fe-shell-navigation/spec.md

Check warning on line 288 in src/components/CollapsibleSection.vue

View workflow job for this annotation

GitHub Actions / quality / Vue Quality (eslint)

Expected JSDoc block to be aligned
*/
handleSave() {
this.$emit('save')
Expand All @@ -295,7 +293,7 @@

/**
* Handle refresh button click
* @spec openspec/specs/fe-shell-navigation/spec.md

Check warning on line 296 in src/components/CollapsibleSection.vue

View workflow job for this annotation

GitHub Actions / quality / Vue Quality (eslint)

Expected JSDoc block to be aligned
*/
handleRefresh() {
this.$emit('refresh')
Expand Down Expand Up @@ -365,73 +363,8 @@
padding: 40px 0;
}

/* Info Modal Styles */
.info-modal {
padding: 20px;
max-width: 600px;
max-height: 80vh;
overflow-y: auto;
}

.modal-header {
margin-bottom: 16px;
padding-bottom: 16px;
border-bottom: 1px solid var(--color-border);
}

.modal-header h2 {
margin: 0;
font-size: 20px;
font-weight: 600;
color: var(--color-main-text);
}

.modal-content {
margin-bottom: 20px;
line-height: 1.6;
}

.modal-content :deep(h3) {
margin-top: 20px;
margin-bottom: 12px;
font-size: 16px;
font-weight: 600;
}

.modal-content :deep(h4) {
margin-top: 16px;
margin-bottom: 8px;
font-size: 14px;
font-weight: 600;
}

.modal-content :deep(ul) {
padding-left: 20px;
margin-bottom: 16px;
}

.modal-content :deep(li) {
margin-bottom: 4px;
}

.modal-content :deep(p) {
margin-bottom: 12px;
}

.modal-content :deep(code) {
background-color: var(--color-background-dark);
padding: 2px 6px;
border-radius: 4px;
font-family: monospace;
font-size: 13px;
}

.modal-footer {
display: flex;
justify-content: flex-end;
padding-top: 16px;
border-top: 1px solid var(--color-border);
}
/* The info-modal styles live with the modal in
src/modals/CollapsibleSectionInfoModal.vue */

/* WCAG 2.3.3 — the expand animation is decorative; a reduced-motion user gets
the expanded section immediately instead of the slide. */
Expand Down
Loading
Loading