mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-03-23 02:35:41 +00:00
refactor(webapp): ds-radio -> html (#9403)
This commit is contained in:
parent
83df85001d
commit
4727eb6eb4
@ -4,7 +4,7 @@ defineStep(/^I confirm the reporting dialog .*:$/, message => {
|
||||
cy.contains(message) // wait for element to become visible
|
||||
cy.get('.os-modal')
|
||||
.within(() => {
|
||||
cy.get('.ds-radio-option-label')
|
||||
cy.get('.report-radio-option')
|
||||
.first()
|
||||
.click({
|
||||
force: true
|
||||
|
||||
@ -13,7 +13,7 @@ Phase 0: Analyse ██████████ 100% (8/8 Schritte) ✅
|
||||
Phase 3: OsButton ██████████ 100% (133/133 Buttons) ✅
|
||||
Phase 4: Tier 1 ██████████ 100% (OsButton, OsIcon, OsSpinner, OsCard) ✅
|
||||
Phase 4: Tier A → HTML ██████████ 100% (10 ds-* Wrapper → Plain HTML) ✅
|
||||
Phase 4: Tier B ████████░░ 80% (ds-chip→OsBadge✅, ds-tag→OsBadge✅, ds-grid✅, ds-number→OsNumber✅, ds-radio⬜)
|
||||
Phase 4: Tier B ██████████ 100% (ds-chip→OsBadge✅, ds-tag→OsBadge✅, ds-grid✅, ds-number→OsNumber✅, ds-radio→HTML✅)
|
||||
Phase 4: Tier B+ ████████░░ 75% (ds-table→HTML✅) | Tier 2 begonnen (OsModal✅) | Rest ausstehend (OsInput, OsMenu, OsSelect)
|
||||
```
|
||||
|
||||
@ -27,7 +27,7 @@ Phase 4: Tier B+ ████████░░ 75% (ds-table→HTML✅)
|
||||
| ✅ → Plain HTML | Section, Placeholder, List, ListItem, Container, Heading, Text, Space, Flex, FlexItem, Grid, GridItem, Table (13) |
|
||||
| ✅ → OsBadge | Chip (20 Nutzungen → OsBadge), Tag (3 → OsBadge shape="square") |
|
||||
| ✅ → OsNumber | Number (5 Nutzungen → OsNumber, CountTo.vue gelöscht, vue-count-to entfernt) |
|
||||
| ⬜ → Plain HTML | Radio (1) — Tier B Rest |
|
||||
| ✅ → Plain HTML | Radio (1 Datei → native `<input type="radio">` in ReportModal) |
|
||||
| ⬜ → UI-Library | Modal, Input, Menu, MenuItem, Select (5) — Tier 2-3 |
|
||||
| ⬜ Offen | Form (18 Dateien — HTML oder OsForm?) |
|
||||
| ⬜ Nicht in Webapp | Code, CopyField, FormItem, InputError, InputLabel, Page, PageTitle, Logo, Avatar, TableCol, TableHeadCol (11) |
|
||||
@ -76,7 +76,7 @@ Phase 4: Tier B+ ████████░░ 75% (ds-table→HTML✅)
|
||||
| 17 | Input | ⬜ Tier 2 | 23 Dateien → OsInput (gekoppelt mit Form) |
|
||||
| 18 | InputError | ⬜ Nicht genutzt | Intern von Input genutzt |
|
||||
| 19 | InputLabel | ⬜ Nicht genutzt | Intern von Input genutzt |
|
||||
| 20 | Radio | ⬜ Tier B | 1 Datei → native `<input type="radio">` |
|
||||
| 20 | Radio | ✅ → HTML | 1 Datei → native `<input type="radio">` + `<fieldset>` (ReportModal) |
|
||||
| 21 | Select | ⬜ Tier 4 | 3 Dateien → OsSelect |
|
||||
|
||||
### Layout
|
||||
@ -439,7 +439,7 @@ Phase 4: Tier B+ ████████░░ 75% (ds-table→HTML✅)
|
||||
15. [x] ds-tag (3 Dateien) → OsBadge shape="square" (UI-Library)
|
||||
16. [x] ds-grid / ds-grid-item (10 Dateien) → CSS Grid (Plain HTML)
|
||||
17. [ ] ds-number (5 Dateien) → `<div class="ds-number">`
|
||||
18. [ ] ds-radio (1 Datei) → native `<input type="radio">`
|
||||
18. [x] ds-radio (1 Datei) → native `<input type="radio">` + `<fieldset>` (ReportModal) ✅
|
||||
|
||||
### Phase 4: Tier 2-4 — UI-Library
|
||||
18. [x] OsModal (h() Render, Focus-Trap, Scroll-Lock, A11y; ConfirmModal + ReportModal nutzen OsModal; DeleteUserModal/DisableModal/ReleaseModal gelöscht) ✅
|
||||
|
||||
@ -81,10 +81,10 @@ Phase 0: ██████████ 100% (6/6 Aufgaben) ✅
|
||||
Phase 1: ██████████ 100% (6/6 Aufgaben) ✅
|
||||
Phase 2: ██████████ 100% (26/26 Aufgaben) ✅
|
||||
Phase 3: ██████████ 100% (24/24 Aufgaben) ✅ - Webapp-Integration komplett
|
||||
Phase 4: ███████░░░ 67% (18/27 Aufgaben) - Tier 1 ✅, Tier A ✅, Infra ✅, OsBadge ✅, ds-grid ✅, ds-table→HTML ✅, OsNumber ✅, OsModal ✅ | Tier B (rest), Tier 2-3 ausstehend
|
||||
Phase 4: ███████░░░ 70% (19/27 Aufgaben) - Tier 1 ✅, Tier A ✅, Infra ✅, OsBadge ✅, ds-grid ✅, ds-table→HTML ✅, OsNumber ✅, OsModal ✅, ds-radio→HTML ✅ | Tier B ✅, Tier 2-3 ausstehend
|
||||
Phase 5: ░░░░░░░░░░ 0% (0/7 Aufgaben)
|
||||
───────────────────────────────────────
|
||||
Gesamt: ████████░░ 83% (80/96 Aufgaben)
|
||||
Gesamt: ████████░░ 84% (81/96 Aufgaben)
|
||||
```
|
||||
|
||||
### Katalogisierung (Details in KATALOG.md)
|
||||
@ -216,11 +216,20 @@ ds-chip + ds-tag → OsBadge (UI-Library): ✅
|
||||
|
||||
## Aktueller Stand
|
||||
|
||||
**Letzte Aktualisierung:** 2026-02-20 (Session 32)
|
||||
**Letzte Aktualisierung:** 2026-03-14 (Session 33)
|
||||
|
||||
**Aktuelle Phase:** Phase 4 - Tier 1 ✅, Tier A ✅, OsBadge ✅, ds-grid ✅, ds-table→HTML ✅, OsNumber ✅ | Tier B (rest), Tier 2-3 ausstehend
|
||||
**Aktuelle Phase:** Phase 4 - Tier 1 ✅, Tier A ✅, Tier B ✅, OsModal ✅ | Tier 2-3 ausstehend
|
||||
|
||||
**Zuletzt abgeschlossen (Session 32 - OsNumber: ds-number + CountTo → OsNumber):**
|
||||
**Zuletzt abgeschlossen (Session 33 - ds-radio → native HTML):**
|
||||
- [x] `<ds-radio>` in ReportModal.vue → native `<fieldset>` + `<input type="radio">` + `<label>`
|
||||
- [x] Accessible Radio-Group: `<fieldset>` mit `<legend>` für Screen-Reader
|
||||
- [x] CSS: `.report-radio-group`, `.report-radio-option`, `.report-radio-option-label` (in ReportModal `<style>`)
|
||||
- [x] ReportModal.spec.js: `.ds-radio-option-label` → `input[type="radio"]` Selektor
|
||||
- [x] Cypress E2E: `.ds-radio-option-label` → `input[type="radio"]` Selektor
|
||||
- [x] 14/14 Unit-Tests bestanden
|
||||
- [x] 0 ds-radio Nutzungen verbleibend
|
||||
|
||||
**Zuvor abgeschlossen (Session 32 - OsNumber: ds-number + CountTo → OsNumber):**
|
||||
- [x] OsNumber Komponente in packages/ui erstellt (h() Render-Function, requestAnimationFrame Animation)
|
||||
- [x] Props: count (required), label (optional), animated (optional, 1500ms ease-out)
|
||||
- [x] Animation: requestAnimationFrame-Loop, watch(count) re-animiert von oldVal→newVal
|
||||
@ -279,8 +288,7 @@ ds-chip + ds-tag → OsBadge (UI-Library): ✅
|
||||
- [x] Test-Fix: Empty.spec.js `attributes().margin` → `classes().toContain('ds-my-xxx-small')`
|
||||
- [x] 0 Tier-A `ds-*` Komponenten-Tags verbleibend
|
||||
|
||||
**Verbleibende ds-* Komponenten (7 Typen):**
|
||||
- Tier B Rest (→ Plain HTML): ds-radio (1)
|
||||
**Verbleibende ds-* Komponenten (6 Typen):**
|
||||
- Tier C (→ UI-Library): ds-input (23), ds-form (18), ds-modal (7), ds-menu/ds-menu-item (17), ds-select (3)
|
||||
|
||||
**Zuvor abgeschlossen (Session 26 - CodeRabbit Review Fixes):**
|
||||
|
||||
@ -162,7 +162,7 @@ describe('ReportModal.vue', () => {
|
||||
|
||||
describe('click confirm button', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper.find('.ds-radio-option-label').trigger('click')
|
||||
wrapper.find('.report-radio-option').trigger('click')
|
||||
await Vue.nextTick()
|
||||
wrapper.find('button.confirm').trigger('click')
|
||||
await Vue.nextTick()
|
||||
|
||||
@ -9,13 +9,26 @@
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<p v-html="message" />
|
||||
<div class="ds-mb-small"></div>
|
||||
<ds-radio
|
||||
v-model="form.reasonCategory"
|
||||
:schema="formSchema.reasonCategory"
|
||||
:label="$t('report.reason.category.label')"
|
||||
:options="form.reasonCategoryOptions"
|
||||
labelProp="label"
|
||||
/>
|
||||
<fieldset class="report-radio-group" data-test="report-radio-group" role="radiogroup">
|
||||
<legend>{{ $t('report.reason.category.label') }}</legend>
|
||||
<div
|
||||
v-for="(option, index) in form.reasonCategoryOptions"
|
||||
:key="option.value"
|
||||
class="report-radio-option"
|
||||
:class="{ 'report-radio-option-selected': form.reasonCategory === option }"
|
||||
role="radio"
|
||||
:aria-checked="String(form.reasonCategory === option)"
|
||||
:tabindex="form.reasonCategory === option || (!form.reasonCategory && index === 0) ? 0 : -1"
|
||||
@click="selectReasonCategory(option)"
|
||||
@keydown.space.prevent="selectReasonCategory(option)"
|
||||
@keydown.enter.prevent="selectReasonCategory(option)"
|
||||
@keydown.down.prevent="focusRadioOption(index + 1)"
|
||||
@keydown.up.prevent="focusRadioOption(index - 1)"
|
||||
>
|
||||
<span class="report-radio-option-mark" />
|
||||
<span class="report-radio-option-label">{{ option.label }}</span>
|
||||
</div>
|
||||
</fieldset>
|
||||
<ds-input
|
||||
class="reason-description"
|
||||
v-model="form.reasonDescription"
|
||||
@ -119,6 +132,18 @@ export default {
|
||||
this.$emit('close')
|
||||
}, 1000)
|
||||
},
|
||||
selectReasonCategory(option) {
|
||||
this.form.reasonCategory = option
|
||||
this.$nextTick(() => {
|
||||
const selected = this.$el.querySelector('.report-radio-option[aria-checked="true"]')
|
||||
if (selected) selected.focus()
|
||||
})
|
||||
},
|
||||
focusRadioOption(index) {
|
||||
const options = this.form.reasonCategoryOptions
|
||||
const wrappedIndex = (index + options.length) % options.length
|
||||
this.selectReasonCategory(options[wrappedIndex])
|
||||
},
|
||||
async confirm() {
|
||||
const { reasonCategory, reasonDescription } = this.form
|
||||
this.loading = true
|
||||
@ -174,12 +199,54 @@ export default {
|
||||
width: 700px !important;
|
||||
max-width: 700px !important;
|
||||
}
|
||||
.report-modal .ds-radio-option {
|
||||
width: 100% !important;
|
||||
.report-modal .report-radio-group {
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.report-modal .ds-radio-option-label {
|
||||
margin: 5px 20px 5px 5px !important;
|
||||
width: 100% !important;
|
||||
.report-modal .report-radio-group legend {
|
||||
font-weight: bold;
|
||||
margin-bottom: $space-xx-small;
|
||||
}
|
||||
.report-modal .report-radio-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 4px 0;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.report-modal .report-radio-option-mark {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
min-width: 16px;
|
||||
border: 2px solid $border-color-base;
|
||||
background-color: $background-color-base;
|
||||
border-radius: 50%;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.report-modal .report-radio-option-mark::before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translateY(-50%) translateX(-50%) scale(0);
|
||||
opacity: 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background-color: $text-color-primary;
|
||||
transition: all 0.1s ease-in;
|
||||
}
|
||||
.report-modal .report-radio-option-selected .report-radio-option-mark::before {
|
||||
opacity: 1;
|
||||
transform: translateY(-50%) translateX(-50%) scale(1);
|
||||
}
|
||||
.report-modal .report-radio-option-label {
|
||||
cursor: pointer;
|
||||
flex: 1;
|
||||
}
|
||||
.report-modal .reason-description {
|
||||
margin-top: $space-x-small !important;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user