@conduction/nextcloud-vue 0.1.0-beta.12 → 0.1.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/nextcloud-vue.cjs.js +19981 -648
  2. package/dist/nextcloud-vue.cjs.js.map +1 -1
  3. package/dist/nextcloud-vue.css +2314 -342
  4. package/dist/nextcloud-vue.esm.js +19982 -648
  5. package/dist/nextcloud-vue.esm.js.map +1 -1
  6. package/l10n/en.json +255 -2
  7. package/l10n/nl.json +247 -2
  8. package/package.json +2 -1
  9. package/src/components/CnAdvancedFormDialog/CnDataTab.vue +1 -4
  10. package/src/components/CnContextMenu/CnContextMenu.vue +1 -1
  11. package/src/components/CnDataTable/CnDataTable.vue +7 -2
  12. package/src/components/CnInfoWidget/CnInfoWidget.vue +0 -1
  13. package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +2 -2
  14. package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +2 -2
  15. package/src/components/CnRowActions/CnRowActions.vue +1 -1
  16. package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +36 -34
  17. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +47 -36
  18. package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +29 -22
  19. package/src/components/CnSchemaFormDialog/CnSchemaPropertyActions.vue +170 -163
  20. package/src/components/CnSchemaFormDialog/CnSchemaSecurityTab.vue +473 -116
  21. package/src/components/CnStatsBlock/CnStatsBlock.vue +18 -18
  22. package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +12 -0
  23. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +7 -7
  24. package/src/composables/useContextMenu.js +1 -1
  25. package/src/css/CnSchemaFormDialog.css +258 -2
  26. package/src/css/dashboard.css +1 -0
  27. package/src/css/detail-page.css +5 -5
  28. package/src/css/index.css +1 -0
  29. package/src/css/patches.css +20 -0
  30. package/src/store/plugins/search.js +7 -7
@@ -267,6 +267,24 @@ export default {
267
267
  min-width: 0;
268
268
  }
269
269
 
270
+ /* Content */
271
+ .cn-stats-block__content {
272
+ flex: 1;
273
+ min-width: 0;
274
+ text-align: center;
275
+ }
276
+
277
+ .cn-stats-block__count {
278
+ display: flex;
279
+ align-items: baseline;
280
+ justify-content: center;
281
+ gap: 0.25rem;
282
+ font-size: 1.2rem;
283
+ margin-bottom: 0.25rem;
284
+ white-space: nowrap;
285
+ overflow: hidden;
286
+ }
287
+
270
288
  .cn-stats-block--horizontal {
271
289
  flex-direction: row;
272
290
  align-items: center;
@@ -336,13 +354,6 @@ export default {
336
354
  color: var(--color-element-error, var(--color-error));
337
355
  }
338
356
 
339
- /* Content */
340
- .cn-stats-block__content {
341
- flex: 1;
342
- min-width: 0;
343
- text-align: center;
344
- }
345
-
346
357
  .cn-stats-block__header h4 {
347
358
  margin-top: 0;
348
359
  margin-bottom: 0.25rem;
@@ -354,17 +365,6 @@ export default {
354
365
  text-overflow: ellipsis;
355
366
  }
356
367
 
357
- .cn-stats-block__count {
358
- display: flex;
359
- align-items: baseline;
360
- justify-content: center;
361
- gap: 0.25rem;
362
- font-size: 1.2rem;
363
- margin-bottom: 0.25rem;
364
- white-space: nowrap;
365
- overflow: hidden;
366
- }
367
-
368
368
  .cn-stats-block__count-value {
369
369
  font-size: 2rem;
370
370
  font-weight: bold;
@@ -86,8 +86,10 @@
86
86
  <!-- Primary action button (Save / Create) -->
87
87
  <NcButton
88
88
  v-if="createAnother || result === null"
89
+ v-tooltip="disableSave && disableSaveTooltip ? disableSaveTooltip : undefined"
89
90
  type="primary"
90
91
  :disabled="loading || disableSave"
92
+ :aria-label="disableSave && disableSaveTooltip ? disableSaveTooltip : undefined"
91
93
  @click="executeConfirm">
92
94
  <template #icon>
93
95
  <NcLoadingIcon v-if="loading" :size="20" />
@@ -204,6 +206,16 @@ export default {
204
206
  type: Boolean,
205
207
  default: false,
206
208
  },
209
+ /**
210
+ * Tooltip shown on the save button when it is disabled.
211
+ * Also used as aria-label so screen readers can explain the blocked state (WCAG 2.1 AA).
212
+ *
213
+ * @type {string}
214
+ */
215
+ disableSaveTooltip: {
216
+ type: String,
217
+ default: '',
218
+ },
207
219
  /**
208
220
  * Custom success message shown in the result NcNoteCard.
209
221
  * Defaults to "{entityName} saved successfully".
@@ -170,6 +170,13 @@ export default {
170
170
  overflow: hidden;
171
171
  }
172
172
 
173
+ .cn-widget-wrapper__content {
174
+ flex: 1;
175
+ overflow: auto;
176
+ min-height: 0;
177
+ padding: 16px;
178
+ }
179
+
173
180
  .cn-widget-wrapper--borderless {
174
181
  border: none;
175
182
  background: transparent;
@@ -214,13 +221,6 @@ export default {
214
221
  text-overflow: ellipsis;
215
222
  }
216
223
 
217
- .cn-widget-wrapper__content {
218
- flex: 1;
219
- overflow: auto;
220
- min-height: 0;
221
- padding: 16px;
222
- }
223
-
224
224
  .cn-widget-wrapper__actions {
225
225
  display: flex;
226
226
  gap: 4px;
@@ -54,7 +54,7 @@ export function useContextMenu() {
54
54
  * Sets CSS custom properties for x/y coordinates and a data attribute on
55
55
  * `document.documentElement` so the shared CSS can override Popper positioning.
56
56
  *
57
- * @param {object} params
57
+ * @param {object} params - Context menu trigger parameters.
58
58
  * @param {any} params.item The item associated with the right-click (row, folder, etc.)
59
59
  * @param {MouseEvent} params.event The native contextmenu event
60
60
  */
@@ -152,6 +152,11 @@
152
152
  background-color: var(--color-primary-light);
153
153
  }
154
154
 
155
+ /* Applied to each td of the row currently being edited so inputs sit at the same baseline */
156
+ .cn-schema-form__editing-cell {
157
+ vertical-align: baseline !important;
158
+ }
159
+
155
160
  .cn-schema-form__viewTable tbody tr.cn-schema-form__modified-row {
156
161
  background-color: var(--color-warning);
157
162
  border-left: 3px solid var(--color-element-warning);
@@ -161,7 +166,9 @@
161
166
  background-color: var(--color-warning);
162
167
  }
163
168
 
164
- .cn-schema-form__viewTable tbody tr.cn-schema-form__modified-row.cn-schema-form__selected-row {
169
+ .cn-schema-form__viewTable
170
+ tbody
171
+ tr.cn-schema-form__modified-row.cn-schema-form__selected-row {
165
172
  background-color: var(--color-primary-light);
166
173
  border-left: 3px solid var(--color-primary);
167
174
  }
@@ -524,6 +531,255 @@
524
531
  color: var(--color-info-text);
525
532
  }
526
533
 
534
+ /* Advanced: Conditional Access Rules — accordion + rule cards */
535
+ .cn-schema-form__conditional-section {
536
+ margin-top: 32px;
537
+ }
538
+
539
+ .cn-schema-form__cond-accordion-header {
540
+ display: flex;
541
+ align-items: center;
542
+ gap: 8px;
543
+ width: 100%;
544
+ padding: 12px 16px;
545
+ background: var(--color-background-dark);
546
+ border: 1px solid var(--color-border);
547
+ border-radius: var(--border-radius-element);
548
+ cursor: pointer;
549
+ font-size: 14px;
550
+ font-weight: 600;
551
+ color: var(--color-main-text);
552
+ text-align: left;
553
+ transition: background var(--animation-quick) ease;
554
+ }
555
+
556
+ .cn-schema-form__cond-accordion-header:hover {
557
+ background: var(--color-background-hover);
558
+ }
559
+
560
+ .cn-schema-form__cond-chevron {
561
+ flex-shrink: 0;
562
+ color: var(--color-text-maxcontrast);
563
+ }
564
+
565
+ .cn-schema-form__cond-count-badge {
566
+ margin-left: auto;
567
+ padding: 2px 8px;
568
+ background: var(--color-primary-element);
569
+ color: var(--color-primary-element-text);
570
+ border-radius: var(--border-radius-pill);
571
+ font-size: 12px;
572
+ font-weight: 600;
573
+ }
574
+
575
+ .cn-schema-form__cond-accordion-body {
576
+ margin-top: 4px;
577
+ border: 1px solid var(--color-border);
578
+ border-radius: var(--border-radius-element);
579
+ padding: 16px;
580
+ display: flex;
581
+ flex-direction: column;
582
+ gap: 4px;
583
+ }
584
+
585
+ /* Per-action container — same border/radius pattern as the RBAC table container */
586
+ .cn-schema-form__cond-action {
587
+ margin-top: 16px;
588
+ border: 1px solid var(--color-border-dark);
589
+ border-radius: var(--border-radius-element);
590
+ /* overflow visible so NcSelect dropdowns (appendToBody:true) can position correctly */
591
+ overflow: visible;
592
+ box-shadow: 0 2px 8px rgba(var(--color-box-shadow-rgb), 0.06);
593
+ }
594
+
595
+ .cn-schema-form__cond-action:first-of-type {
596
+ margin-top: 12px;
597
+ }
598
+
599
+ /* Action header — matches RBAC table <th> row */
600
+ .cn-schema-form__cond-action-header {
601
+ display: flex;
602
+ align-items: center;
603
+ justify-content: space-between;
604
+ padding: 10px 16px;
605
+ background: var(--color-background-dark);
606
+ border-bottom: 2px solid var(--color-border-dark);
607
+ border-radius: var(--border-radius-element) var(--border-radius-element) 0 0;
608
+ }
609
+
610
+ .cn-schema-form__cond-action-name {
611
+ font-size: 14px;
612
+ font-weight: 600;
613
+ color: var(--color-main-text);
614
+ text-transform: capitalize;
615
+ }
616
+
617
+ .cn-schema-form__cond-empty {
618
+ padding: 12px 16px;
619
+ color: var(--color-text-maxcontrast);
620
+ font-style: italic;
621
+ font-size: 13px;
622
+ background: var(--color-main-background);
623
+ }
624
+
625
+ /* Rule card — standalone card so each rule is visually distinct */
626
+ .cn-schema-form__cond-rule-card {
627
+ margin: 8px;
628
+ padding: 14px 16px;
629
+ background: var(--color-main-background);
630
+ border: 1px solid var(--color-border);
631
+ border-radius: var(--border-radius-element);
632
+ display: flex;
633
+ flex-direction: column;
634
+ gap: 12px;
635
+ overflow: visible;
636
+ box-shadow: 0 1px 4px rgba(var(--color-box-shadow-rgb), 0.08);
637
+ transition: background var(--animation-quick) ease,
638
+ box-shadow var(--animation-quick) ease;
639
+ }
640
+
641
+ /* Group-based left border — same color variables as the group badges in the RBAC table */
642
+ .cn-schema-form__cond-rule-card--public {
643
+ border-left: 3px solid var(--color-info);
644
+ }
645
+ .cn-schema-form__cond-rule-card--authenticated {
646
+ border-left: 3px solid var(--color-warning);
647
+ }
648
+ .cn-schema-form__cond-rule-card--admin {
649
+ border-left: 3px solid var(--color-success);
650
+ }
651
+
652
+ /* Rule header row: group badge + select + remove button */
653
+ .cn-schema-form__cond-rule-header {
654
+ display: flex;
655
+ align-items: center;
656
+ gap: 12px;
657
+ }
658
+
659
+ /* Suppress the badge text since the select already shows the group */
660
+ .cn-schema-form__cond-rule-header .cn-schema-form__group-badge {
661
+ display: none;
662
+ }
663
+
664
+ .cn-schema-form__cond-rule-group-select {
665
+ flex: 1;
666
+ max-width: 260px;
667
+ }
668
+
669
+ /* Remove extra spacing from vue-select so the group select aligns with the Remove rule button */
670
+ .cn-schema-form__cond-rule-group-select .v-select {
671
+ margin: 0;
672
+ }
673
+ .cn-schema-form__cond-rule-group-select .vs__dropdown-toggle {
674
+ padding-bottom: 0;
675
+ }
676
+
677
+ /* Conditions list */
678
+ .cn-schema-form__cond-match-list {
679
+ padding-left: 4px;
680
+ }
681
+
682
+ .cn-schema-form__cond-match-empty {
683
+ font-size: 12px;
684
+ font-style: italic;
685
+ color: var(--color-text-maxcontrast);
686
+ padding: 4px 0;
687
+ margin: 0;
688
+ }
689
+
690
+ .cn-schema-form__cond-match-table {
691
+ width: 100%;
692
+ border-collapse: collapse;
693
+ border: 1px solid var(--color-border-dark);
694
+ border-radius: var(--border-radius-element);
695
+ overflow: hidden;
696
+ box-shadow: 0 2px 8px rgba(var(--color-box-shadow-rgb), 0.1);
697
+ }
698
+
699
+ /* stylelint-disable-next-line no-descending-specificity */
700
+ .cn-schema-form__cond-match-table th {
701
+ background: var(--color-background-dark);
702
+ color: var(--color-main-text);
703
+ font-weight: 600;
704
+ padding: 10px 16px;
705
+ text-align: left;
706
+ border-bottom: 2px solid var(--color-border-dark);
707
+ }
708
+
709
+ /* stylelint-disable-next-line no-descending-specificity */
710
+ .cn-schema-form__cond-match-table td {
711
+ padding: 10px 16px;
712
+ vertical-align: middle;
713
+ border-bottom: 1px solid var(--color-border);
714
+ }
715
+
716
+ .cn-schema-form__cond-match-table tbody tr:last-child td {
717
+ border-bottom: none;
718
+ }
719
+
720
+ .cn-schema-form__cond-match-actions {
721
+ width: 44px;
722
+ text-align: right;
723
+ }
724
+
725
+ /* Add-condition inline form */
726
+ .cn-schema-form__cond-add-form {
727
+ display: flex;
728
+ flex-direction: column;
729
+ gap: 12px;
730
+ padding: 14px;
731
+ background: var(--color-background-hover);
732
+ border-radius: var(--border-radius);
733
+ border: 1px dashed var(--color-border-dark);
734
+ }
735
+
736
+ /* Three equal columns for Property / Operator / Value selects */
737
+ .cn-schema-form__cond-add-row {
738
+ display: grid;
739
+ grid-template-columns: repeat(3, minmax(0, 1fr));
740
+ gap: 12px;
741
+ align-items: start;
742
+ }
743
+
744
+ .cn-schema-form__cond-add-field {
745
+ min-width: 0;
746
+ }
747
+
748
+ /* NcSelect (vue-select) must fill its grid cell */
749
+ .cn-schema-form__cond-add-field .v-select {
750
+ width: 100%;
751
+ min-width: 0;
752
+ }
753
+
754
+ /* Custom value input — full width below the three selects, never displaces them */
755
+ .cn-schema-form__cond-custom-row {
756
+ display: flex;
757
+ flex-direction: column;
758
+ gap: 6px;
759
+ }
760
+
761
+ .cn-schema-form__cond-custom-input {
762
+ width: 100%;
763
+ height: 34px;
764
+ padding: 4px 10px;
765
+ border: 1px solid var(--color-border-dark);
766
+ border-radius: var(--border-radius);
767
+ background: var(--color-main-background);
768
+ color: var(--color-main-text);
769
+ font-size: 13px;
770
+ box-sizing: border-box;
771
+ }
772
+
773
+ .cn-schema-form__cond-custom-input:focus {
774
+ outline: 2px solid var(--color-primary-element);
775
+ outline-offset: -1px;
776
+ }
777
+
778
+ .cn-schema-form__cond-add-actions {
779
+ display: flex;
780
+ gap: 8px;
781
+ }
782
+
527
783
  /* Copied from openregister/SolrWarmupModal — also used in other files */
528
784
  .cn-schema-form__schema-option {
529
785
  display: flex;
@@ -541,6 +797,6 @@
541
797
  word-break: break-word;
542
798
  display: -webkit-box;
543
799
  -webkit-line-clamp: 2;
544
- -webkit-box-orient: vertical;
800
+ -webkit-box-orient: vertical;
545
801
  overflow: hidden;
546
802
  }
@@ -7,6 +7,7 @@
7
7
  }
8
8
 
9
9
  /* Widget grid item borders for non-tile widgets */
10
+ /* stylelint-disable-next-line selector-pseudo-class-no-unknown */
10
11
  .cn-dashboard-grid :deep(.grid-stack-item-content:has(.cn-widget-wrapper)) {
11
12
  border: 1px solid var(--color-border);
12
13
  }
@@ -121,6 +121,11 @@
121
121
  border-bottom: 1px solid var(--color-border);
122
122
  }
123
123
 
124
+ .cn-detail-page__stats-row--sub td {
125
+ color: var(--color-text-maxcontrast);
126
+ font-size: 0.9em;
127
+ }
128
+
124
129
  .cn-detail-page__stats-table tbody td {
125
130
  padding: calc(1.5 * var(--default-grid-baseline)) calc(2 * var(--default-grid-baseline));
126
131
  border-bottom: 1px solid var(--color-border-dark);
@@ -132,11 +137,6 @@
132
137
  border-bottom: none;
133
138
  }
134
139
 
135
- .cn-detail-page__stats-row--sub td {
136
- color: var(--color-text-maxcontrast);
137
- font-size: 0.9em;
138
- }
139
-
140
140
  .cn-detail-page__stats-cell--indented {
141
141
  padding-left: calc(5 * var(--default-grid-baseline)) !important;
142
142
  }
package/src/css/index.css CHANGED
@@ -15,3 +15,4 @@
15
15
  @import './CnSchemaFormDialog.css';
16
16
  @import './timeline-stages.css';
17
17
  @import './context-menu.css';
18
+ @import './patches.css';
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Global theme override for NcDateTimePicker's disabled calendar cells.
3
+ * The underlying vue2-datepicker library ships hardcoded `#f3f3f3` / `#ccc`,
4
+ * which breaks dark mode. The popup is portaled to <body>, so this must be
5
+ * unscoped and lives here rather than in each modal that uses the picker.
6
+ */
7
+ .mx-calendar-content .cell.disabled {
8
+ background-color: var(--color-background-dark) !important;
9
+ color: var(--color-text-maxcontrast) !important;
10
+ cursor: not-allowed;
11
+ }
12
+
13
+ .mx-calendar-content .cell.disabled,
14
+ .mx-calendar-content .cell.disabled * {
15
+ cursor: not-allowed !important;
16
+ }
17
+
18
+ .mx-calendar-content .cell.disabled:hover {
19
+ background-color: var(--color-background-dark) !important;
20
+ }
@@ -99,25 +99,25 @@ export function searchPlugin() {
99
99
  */
100
100
  searchVisibleColumns: [],
101
101
 
102
- /** @private @type {Array} */
102
+ /** @private */
103
103
  _searchCollection: [],
104
104
 
105
- /** @private @type {{ total: number, page: number, pages: number, limit: number }} */
105
+ /** @private */
106
106
  _searchPagination: { total: 0, page: 1, pages: 1, limit: 20 },
107
107
 
108
- /** @private @type {boolean} */
108
+ /** @private */
109
109
  _searchLoading: false,
110
110
 
111
- /** @private @type {object|null} */
111
+ /** @private */
112
112
  _searchSchema: null,
113
113
 
114
- /** @private @type {object|null} */
114
+ /** @private */
115
115
  _searchRegister: null,
116
116
 
117
- /** @private @type {object} */
117
+ /** @private */
118
118
  _searchFacets: {},
119
119
 
120
- /** @private @type {number} Request sequence counter to prevent race conditions */
120
+ /** @private */
121
121
  _searchRequestId: 0,
122
122
  }),
123
123