@globalbrain/sefirot 4.30.1 → 4.32.0
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.
- package/client.d.ts +5 -0
- package/config/nuxt.d.ts +1 -0
- package/config/nuxt.js +8 -5
- package/config/vite.js +4 -13
- package/lib/components/SActionList.vue +2 -2
- package/lib/components/SActionMenu.vue +43 -7
- package/lib/components/SAvatar.vue +1 -1
- package/lib/components/SAvatarStack.vue +12 -12
- package/lib/components/SButton.vue +5 -7
- package/lib/components/SCard.vue +2 -2
- package/lib/components/SChartBar.vue +37 -12
- package/lib/components/SChartPie.vue +13 -7
- package/lib/components/SControlActionBarCollapse.vue +2 -4
- package/lib/components/SControlInputSearch.vue +7 -2
- package/lib/components/SDataListItem.vue +1 -3
- package/lib/components/SDescAvatar.vue +1 -1
- package/lib/components/SDescDay.vue +2 -2
- package/lib/components/SDescFile.vue +2 -4
- package/lib/components/SDescItem.vue +2 -1
- package/lib/components/SDescLabel.vue +1 -1
- package/lib/components/SDescLink.vue +2 -7
- package/lib/components/SDescPill.vue +2 -4
- package/lib/components/SDescText.vue +3 -3
- package/lib/components/SDropdown.vue +1 -1
- package/lib/components/SDropdownSectionFilter.vue +11 -11
- package/lib/components/SFragment.vue +1 -1
- package/lib/components/SInputAddon.vue +13 -11
- package/lib/components/SInputBase.vue +11 -11
- package/lib/components/SInputCheckbox.vue +6 -3
- package/lib/components/SInputCheckboxes.vue +7 -3
- package/lib/components/SInputDate.vue +3 -5
- package/lib/components/SInputDropdown.vue +26 -28
- package/lib/components/SInputDropdownItem.vue +21 -11
- package/lib/components/SInputFile.vue +9 -6
- package/lib/components/SInputFileUpload.vue +9 -11
- package/lib/components/SInputFileUploadItem.vue +8 -4
- package/lib/components/SInputHMS.vue +3 -1
- package/lib/components/SInputImage.vue +4 -2
- package/lib/components/SInputNumber.vue +9 -10
- package/lib/components/SInputRadio.vue +3 -2
- package/lib/components/SInputRadios.vue +6 -5
- package/lib/components/SInputSegments.vue +5 -7
- package/lib/components/SInputSegmentsOption.vue +1 -2
- package/lib/components/SInputSelect.vue +6 -4
- package/lib/components/SInputSwitch.vue +4 -1
- package/lib/components/SInputSwitches.vue +5 -3
- package/lib/components/SInputText.vue +16 -16
- package/lib/components/SInputTextarea.vue +7 -3
- package/lib/components/SInputYMD.vue +3 -1
- package/lib/components/SLink.vue +2 -2
- package/lib/components/SLocalNav.vue +1 -1
- package/lib/components/SLocalNavActions.vue +1 -1
- package/lib/components/SLocalNavMenu.vue +2 -2
- package/lib/components/SLoginPagePasswordDialog.vue +2 -2
- package/lib/components/SM.vue +1 -1
- package/lib/components/SMFade.vue +1 -1
- package/lib/components/SMarkdown.vue +3 -2
- package/lib/components/SModal.vue +2 -2
- package/lib/components/SSnackbar.vue +2 -2
- package/lib/components/SSteps.vue +6 -6
- package/lib/components/STable.vue +70 -27
- package/lib/components/STableCell.vue +14 -17
- package/lib/components/STableCellAvatars.vue +1 -1
- package/lib/components/STableCellDay.vue +12 -5
- package/lib/components/STableCellNumber.vue +2 -3
- package/lib/components/STableCellPath.vue +2 -2
- package/lib/components/STableCellText.vue +2 -3
- package/lib/components/STableColumn.vue +38 -16
- package/lib/components/STableFooter.vue +10 -2
- package/lib/components/STableHeader.vue +0 -1
- package/lib/components/STableHeaderMenu.vue +4 -4
- package/lib/components/STableHeaderMenuItem.vue +1 -1
- package/lib/components/STooltip.vue +3 -3
- package/lib/composables/Api.ts +1 -1
- package/lib/composables/App.ts +13 -11
- package/lib/composables/Dropdown.ts +10 -1
- package/lib/composables/Error.ts +37 -37
- package/lib/composables/Grid.ts +1 -4
- package/lib/composables/Image.ts +2 -3
- package/lib/composables/Lang.ts +8 -16
- package/lib/composables/Markdown.ts +1 -1
- package/lib/composables/Table.ts +0 -2
- package/lib/composables/Theme.ts +1 -13
- package/lib/composables/Utils.ts +11 -4
- package/lib/composables/Validation.ts +1 -4
- package/lib/http/Http.ts +23 -17
- package/lib/styles/variables-deprecated.css +0 -1
- package/lib/styles/variables.css +16 -16
- package/lib/support/Chart.ts +0 -1
- package/lib/support/DateRange.ts +1 -1
- package/lib/support/Day.ts +12 -65
- package/lib/support/File.ts +7 -16
- package/lib/support/Utils.ts +7 -40
- package/lib/validation/Rule.ts +6 -21
- package/lib/validation/rules/decimal.ts +3 -3
- package/lib/validation/rules/email.ts +1 -1
- package/lib/validation/rules/index.ts +1 -1
- package/lib/validation/rules/negativeInteger.ts +1 -1
- package/lib/validation/rules/positiveInteger.ts +1 -1
- package/lib/validation/rules/requiredHms.ts +2 -2
- package/lib/validation/rules/requiredIf.ts +1 -4
- package/lib/validation/rules/requiredYmd.ts +2 -2
- package/lib/validation/rules/slackChannelName.ts +4 -1
- package/lib/validation/rules/zeroOrNegativeInteger.ts +1 -1
- package/lib/validation/rules/zeroOrPositiveInteger.ts +1 -1
- package/lib/validation/validators/after.ts +1 -5
- package/lib/validation/validators/afterOrEqual.ts +1 -5
- package/lib/validation/validators/before.ts +1 -4
- package/lib/validation/validators/beforeOrEqual.ts +1 -5
- package/lib/validation/validators/decimal.ts +7 -9
- package/lib/validation/validators/email.ts +4 -8
- package/lib/validation/validators/fileExtension.ts +7 -15
- package/lib/validation/validators/hms.ts +26 -15
- package/lib/validation/validators/index.ts +0 -2
- package/lib/validation/validators/maxFileSize.ts +3 -13
- package/lib/validation/validators/maxLength.ts +1 -7
- package/lib/validation/validators/maxTotalFileSize.ts +3 -26
- package/lib/validation/validators/maxValue.ts +2 -6
- package/lib/validation/validators/minLength.ts +1 -7
- package/lib/validation/validators/minValue.ts +2 -6
- package/lib/validation/validators/month.ts +1 -7
- package/lib/validation/validators/negativeInteger.ts +1 -7
- package/lib/validation/validators/positiveInteger.ts +1 -7
- package/lib/validation/validators/required.ts +5 -28
- package/lib/validation/validators/requiredHmsIf.ts +11 -13
- package/lib/validation/validators/requiredIf.ts +5 -11
- package/lib/validation/validators/requiredYmdIf.ts +11 -13
- package/lib/validation/validators/slackChannelName.ts +11 -11
- package/lib/validation/validators/url.ts +7 -5
- package/lib/validation/validators/ymd.ts +36 -30
- package/package.json +44 -42
- package/lib/composables/Http.ts +0 -18
- package/lib/validation/validators/requiredHms.ts +0 -9
- package/lib/validation/validators/requiredYmd.ts +0 -9
|
@@ -22,6 +22,7 @@ const head = shallowRef<HTMLElement | null>(null)
|
|
|
22
22
|
const body = shallowRef<HTMLElement | null>(null)
|
|
23
23
|
const block = shallowRef<HTMLElement | null>(null)
|
|
24
24
|
const row = shallowRef<HTMLElement | null>(null)
|
|
25
|
+
const table = shallowRef<HTMLElement | null>(null)
|
|
25
26
|
|
|
26
27
|
const ordersToShow = smartComputed(() => {
|
|
27
28
|
const orders = unref(props.options.orders).filter((key) => {
|
|
@@ -36,7 +37,7 @@ const ordersToShow = smartComputed(() => {
|
|
|
36
37
|
return ['__select', ...orders]
|
|
37
38
|
})
|
|
38
39
|
|
|
39
|
-
watch(() => ordersToShow.value,
|
|
40
|
+
watch(() => ordersToShow.value, onResize)
|
|
40
41
|
|
|
41
42
|
const colToGrowAdjusted = ref(false)
|
|
42
43
|
|
|
@@ -61,6 +62,12 @@ const cellOfColToGrow = computed(() => {
|
|
|
61
62
|
const colWidths = reactive<Record<string, string>>({})
|
|
62
63
|
const blockWidth = ref<number | undefined>()
|
|
63
64
|
|
|
65
|
+
const resizeState = ref<{
|
|
66
|
+
columnName: string
|
|
67
|
+
startX: number
|
|
68
|
+
indicatorX: number
|
|
69
|
+
} | null>(null)
|
|
70
|
+
|
|
64
71
|
watch(() => unref(props.options.columns), (columns) => {
|
|
65
72
|
Object.keys(columns).forEach((key) => {
|
|
66
73
|
const width = columns[key]?.width
|
|
@@ -77,7 +84,6 @@ const showHeader = computed(() => {
|
|
|
77
84
|
|
|
78
85
|
return (
|
|
79
86
|
unref(props.options.total) != null
|
|
80
|
-
|| !!unref(props.options.reset)
|
|
81
87
|
|| !!unref(props.options.menu)
|
|
82
88
|
)
|
|
83
89
|
})
|
|
@@ -201,7 +207,6 @@ const frozenColumns = smartComputed(() => {
|
|
|
201
207
|
})
|
|
202
208
|
|
|
203
209
|
const frozenColWidths = smartComputed(() => {
|
|
204
|
-
// eslint-disable-next-line no-void
|
|
205
210
|
void blockWidth.value
|
|
206
211
|
return frozenColumns.value.map((key) => getColWidth(key))
|
|
207
212
|
})
|
|
@@ -210,7 +215,7 @@ useResizeObserver(block, ([entry]) => {
|
|
|
210
215
|
blockWidth.value = entry.contentRect.width
|
|
211
216
|
})
|
|
212
217
|
|
|
213
|
-
const resizeObserver = useResizeObserver(head,
|
|
218
|
+
const resizeObserver = useResizeObserver(head, onResize)
|
|
214
219
|
|
|
215
220
|
const font = typeof document !== 'undefined'
|
|
216
221
|
? `500 12px ${getComputedStyle(document.body).fontFamily}`
|
|
@@ -267,7 +272,7 @@ function stopObserving() {
|
|
|
267
272
|
resizeObserver.stop()
|
|
268
273
|
}
|
|
269
274
|
|
|
270
|
-
async function
|
|
275
|
+
async function onResize() {
|
|
271
276
|
if (colToGrow.value < 0 || !cellOfColToGrow.value || !row.value) {
|
|
272
277
|
stopObserving()
|
|
273
278
|
return
|
|
@@ -387,6 +392,29 @@ function getStyles(key: string) {
|
|
|
387
392
|
'--table-col-left': widthSum ? `calc(${widthSum})` : '0px'
|
|
388
393
|
}
|
|
389
394
|
}
|
|
395
|
+
|
|
396
|
+
function onResizeStart(data: { columnName: string; startX: number; initialX: number }) {
|
|
397
|
+
const tableRect = table.value?.getBoundingClientRect()
|
|
398
|
+
const tableLeft = tableRect?.left ?? 0
|
|
399
|
+
const indicatorX = data.initialX - tableLeft
|
|
400
|
+
|
|
401
|
+
resizeState.value = {
|
|
402
|
+
columnName: data.columnName,
|
|
403
|
+
startX: indicatorX,
|
|
404
|
+
indicatorX
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function onResizeMove(data: { deltaX: number }) {
|
|
409
|
+
if (resizeState.value) {
|
|
410
|
+
resizeState.value.indicatorX = resizeState.value.startX + data.deltaX
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function onResizeEnd(data: { columnName: string; finalWidth: string }) {
|
|
415
|
+
updateColWidth(data.columnName, data.finalWidth, true)
|
|
416
|
+
resizeState.value = null
|
|
417
|
+
}
|
|
390
418
|
</script>
|
|
391
419
|
|
|
392
420
|
<template>
|
|
@@ -395,17 +423,21 @@ function getStyles(key: string) {
|
|
|
395
423
|
<STableHeader
|
|
396
424
|
v-if="showHeader"
|
|
397
425
|
:total="unref(options.total)"
|
|
398
|
-
:reset="unref(options.reset)"
|
|
399
426
|
:menu="unref(options.menu)"
|
|
400
427
|
:borderless="unref(options.borderless)"
|
|
401
|
-
:on-reset="options.onReset"
|
|
402
428
|
:selected="Array.isArray(selected) ? selected : undefined"
|
|
403
429
|
/>
|
|
404
430
|
|
|
405
|
-
<div class="table" role="grid">
|
|
406
|
-
<div
|
|
407
|
-
|
|
408
|
-
|
|
431
|
+
<div ref="table" class="table" role="grid">
|
|
432
|
+
<div
|
|
433
|
+
v-if="resizeState"
|
|
434
|
+
class="resize-indicator"
|
|
435
|
+
:style="{ left: `${resizeState.indicatorX}px` }"
|
|
436
|
+
/>
|
|
437
|
+
|
|
438
|
+
<div ref="head" class="container head" @scroll="syncHeadScroll">
|
|
439
|
+
<div ref="block" class="block">
|
|
440
|
+
<div ref="row" class="row">
|
|
409
441
|
<STableItem
|
|
410
442
|
v-for="key in ordersToShow"
|
|
411
443
|
:key
|
|
@@ -421,7 +453,9 @@ function getStyles(key: string) {
|
|
|
421
453
|
:dropdown="unref(options.columns)[key]?.dropdown"
|
|
422
454
|
:has-header="showHeader"
|
|
423
455
|
:resizable="unref(options.columns)[key]?.resizable"
|
|
424
|
-
@resize="
|
|
456
|
+
@resize-start="onResizeStart"
|
|
457
|
+
@resize-move="onResizeMove"
|
|
458
|
+
@resize-end="onResizeEnd"
|
|
425
459
|
>
|
|
426
460
|
<SInputCheckbox
|
|
427
461
|
v-if="
|
|
@@ -440,8 +474,8 @@ function getStyles(key: string) {
|
|
|
440
474
|
|
|
441
475
|
<div
|
|
442
476
|
v-if="!unref(options.loading) && unref(options.records)?.length"
|
|
443
|
-
class="container body"
|
|
444
477
|
ref="body"
|
|
478
|
+
class="container body"
|
|
445
479
|
@scroll="syncBodyScroll"
|
|
446
480
|
>
|
|
447
481
|
<div
|
|
@@ -452,10 +486,10 @@ function getStyles(key: string) {
|
|
|
452
486
|
position: 'relative'
|
|
453
487
|
}"
|
|
454
488
|
>
|
|
455
|
-
<div v-for="{ index, key: __key, size, start } in virtualItems" :key="__key">
|
|
489
|
+
<div v-for="{ index: i, key: __key, size, start } in virtualItems" :key="__key">
|
|
456
490
|
<div
|
|
457
491
|
class="row"
|
|
458
|
-
:class="isSummaryOrLastClass(
|
|
492
|
+
:class="isSummaryOrLastClass(i)"
|
|
459
493
|
:style="{
|
|
460
494
|
position: 'absolute',
|
|
461
495
|
top: 0,
|
|
@@ -475,25 +509,24 @@ function getStyles(key: string) {
|
|
|
475
509
|
>
|
|
476
510
|
<STableCell
|
|
477
511
|
:name="key"
|
|
478
|
-
:class="isSummary(
|
|
512
|
+
:class="isSummary(i) && 'summary'"
|
|
479
513
|
:class-name="unref(options.columns)[key]?.className"
|
|
480
|
-
:cell="getCell(key,
|
|
481
|
-
:value="recordsWithSummary[
|
|
482
|
-
:record="recordsWithSummary[
|
|
483
|
-
:records="unref(options.records)!"
|
|
514
|
+
:cell="getCell(key, i)"
|
|
515
|
+
:value="recordsWithSummary[i][key]"
|
|
516
|
+
:record="recordsWithSummary[i]"
|
|
484
517
|
>
|
|
485
|
-
<template v-if="key === '__select' && !isSummary(
|
|
518
|
+
<template v-if="key === '__select' && !isSummary(i)">
|
|
486
519
|
<SInputCheckbox
|
|
487
520
|
v-if="Array.isArray(selected)"
|
|
488
|
-
:model-value="selected.includes(indexes[
|
|
489
|
-
|
|
490
|
-
:
|
|
521
|
+
:model-value="selected.includes(indexes[i])"
|
|
522
|
+
:disabled="options.disableSelection?.(recordsWithSummary[i]) === true"
|
|
523
|
+
@update:model-value="(c) => (c ? addSelected : removeSelected)(indexes[i])"
|
|
491
524
|
/>
|
|
492
525
|
<SInputRadio
|
|
493
526
|
v-else
|
|
494
|
-
:model-value="selected === indexes[
|
|
495
|
-
|
|
496
|
-
:
|
|
527
|
+
:model-value="selected === indexes[i]"
|
|
528
|
+
:disabled="options.disableSelection?.(recordsWithSummary[i]) === true"
|
|
529
|
+
@update:model-value="(c) => updateSelected(c ? indexes[i] : null)"
|
|
497
530
|
/>
|
|
498
531
|
</template>
|
|
499
532
|
</STableCell>
|
|
@@ -637,6 +670,16 @@ function getStyles(key: string) {
|
|
|
637
670
|
color: var(--c-text-1);
|
|
638
671
|
}
|
|
639
672
|
|
|
673
|
+
.resize-indicator {
|
|
674
|
+
position: absolute;
|
|
675
|
+
top: 0;
|
|
676
|
+
bottom: 0;
|
|
677
|
+
width: 1px;
|
|
678
|
+
background-color: var(--c-border-info-1);
|
|
679
|
+
z-index: 200;
|
|
680
|
+
pointer-events: none;
|
|
681
|
+
}
|
|
682
|
+
|
|
640
683
|
.STable .col-__select {
|
|
641
684
|
--table-col-width: calc(48px + var(--table-padding-left));
|
|
642
685
|
|
|
@@ -21,13 +21,10 @@ const props = defineProps<{
|
|
|
21
21
|
cell?: any
|
|
22
22
|
value: any
|
|
23
23
|
record: any
|
|
24
|
-
records: Record<string, any>
|
|
25
24
|
}>()
|
|
26
25
|
|
|
27
26
|
const computedCell = computed<TableCell | undefined>(() =>
|
|
28
|
-
typeof props.cell === 'function'
|
|
29
|
-
? props.cell(props.value, props.record)
|
|
30
|
-
: props.cell
|
|
27
|
+
typeof props.cell === 'function' ? props.cell(props.value, props.record) : props.cell
|
|
31
28
|
)
|
|
32
29
|
</script>
|
|
33
30
|
|
|
@@ -39,7 +36,7 @@ const computedCell = computed<TableCell | undefined>(() =>
|
|
|
39
36
|
:record
|
|
40
37
|
:align="computedCell?.align"
|
|
41
38
|
:icon="computedCell?.icon"
|
|
42
|
-
:text="computedCell?.value"
|
|
39
|
+
:text="computedCell?.value ?? value"
|
|
43
40
|
:link="computedCell?.link"
|
|
44
41
|
:color="computedCell?.color"
|
|
45
42
|
:icon-color="computedCell?.iconColor"
|
|
@@ -51,7 +48,7 @@ const computedCell = computed<TableCell | undefined>(() =>
|
|
|
51
48
|
:record
|
|
52
49
|
:align="computedCell.align"
|
|
53
50
|
:icon="computedCell.icon"
|
|
54
|
-
:number="computedCell.value"
|
|
51
|
+
:number="computedCell.value ?? value"
|
|
55
52
|
:separator="computedCell.separator"
|
|
56
53
|
:link="computedCell.link"
|
|
57
54
|
:color="computedCell.color"
|
|
@@ -60,47 +57,47 @@ const computedCell = computed<TableCell | undefined>(() =>
|
|
|
60
57
|
/>
|
|
61
58
|
<STableCellPath
|
|
62
59
|
v-else-if="computedCell.type === 'path'"
|
|
63
|
-
:segments="computedCell.segments"
|
|
60
|
+
:segments="computedCell.segments ?? value"
|
|
64
61
|
/>
|
|
65
62
|
<STableCellDay
|
|
66
63
|
v-else-if="computedCell.type === 'day'"
|
|
67
64
|
:align="computedCell.align"
|
|
68
|
-
:day="computedCell.value"
|
|
65
|
+
:day="computedCell.value ?? value"
|
|
69
66
|
:format="computedCell.format"
|
|
70
67
|
:color="computedCell.color"
|
|
71
68
|
/>
|
|
72
69
|
<STableCellPill
|
|
73
70
|
v-else-if="computedCell.type === 'pill'"
|
|
74
|
-
:pill="computedCell.value"
|
|
71
|
+
:pill="computedCell.value ?? value"
|
|
75
72
|
:color="computedCell.color"
|
|
76
73
|
/>
|
|
77
74
|
<STableCellPills
|
|
78
75
|
v-else-if="computedCell.type === 'pills'"
|
|
79
|
-
:pills="computedCell.pills"
|
|
76
|
+
:pills="computedCell.pills ?? value"
|
|
80
77
|
/>
|
|
81
78
|
<STableCellState
|
|
82
79
|
v-else-if="computedCell.type === 'state'"
|
|
83
|
-
:state="computedCell.label"
|
|
80
|
+
:state="computedCell.label ?? value"
|
|
84
81
|
:mode="computedCell.mode"
|
|
85
82
|
/>
|
|
86
83
|
<STableCellIndicator
|
|
87
84
|
v-else-if="computedCell.type === 'indicator'"
|
|
88
|
-
:state="computedCell.state"
|
|
85
|
+
:state="computedCell.state ?? value"
|
|
89
86
|
:label="computedCell.label"
|
|
90
87
|
/>
|
|
91
88
|
<STableCellAvatar
|
|
92
89
|
v-else-if="computedCell.type === 'avatar'"
|
|
93
90
|
:value
|
|
94
91
|
:record
|
|
95
|
-
:image="computedCell.image"
|
|
96
|
-
:name="computedCell.name"
|
|
92
|
+
:image="computedCell.image ?? (value as string).includes('/') ? value : null"
|
|
93
|
+
:name="computedCell.name ?? (value as string).includes('/') ? null : value"
|
|
97
94
|
:link="computedCell.link"
|
|
98
95
|
:color="computedCell.color"
|
|
99
96
|
:on-click="computedCell.onClick"
|
|
100
97
|
/>
|
|
101
98
|
<STableCellAvatars
|
|
102
99
|
v-else-if="computedCell.type === 'avatars'"
|
|
103
|
-
:avatars="computedCell.avatars"
|
|
100
|
+
:avatars="computedCell.avatars ?? value"
|
|
104
101
|
:color="computedCell.color"
|
|
105
102
|
:avatar-count="computedCell.avatarCount"
|
|
106
103
|
:name-count="computedCell.nameCount"
|
|
@@ -109,7 +106,7 @@ const computedCell = computed<TableCell | undefined>(() =>
|
|
|
109
106
|
<STableCellActions
|
|
110
107
|
v-else-if="computedCell.type === 'actions'"
|
|
111
108
|
:record
|
|
112
|
-
:actions="computedCell.actions"
|
|
109
|
+
:actions="computedCell.actions ?? value"
|
|
113
110
|
/>
|
|
114
111
|
<STableCellCustom
|
|
115
112
|
v-else-if="computedCell.type === 'custom'"
|
|
@@ -120,8 +117,8 @@ const computedCell = computed<TableCell | undefined>(() =>
|
|
|
120
117
|
v-else-if="computedCell.type === 'empty'"
|
|
121
118
|
/>
|
|
122
119
|
<component
|
|
123
|
-
v-else-if="computedCell.type === 'component'"
|
|
124
120
|
:is="computedCell.component"
|
|
121
|
+
v-else-if="computedCell.type === 'component'"
|
|
125
122
|
:value
|
|
126
123
|
:record
|
|
127
124
|
v-bind="computedCell.props"
|
|
@@ -48,7 +48,7 @@ const displayNames = computed(() => {
|
|
|
48
48
|
<div class="STableCellAvatars" :class="[color]">
|
|
49
49
|
<div class="container">
|
|
50
50
|
<div v-if="displayAvatars.length" class="avatars">
|
|
51
|
-
<div v-for="(avatar,
|
|
51
|
+
<div v-for="(avatar, i) in displayAvatars" :key="i" class="avatar">
|
|
52
52
|
<div class="avatar-box">
|
|
53
53
|
<SAvatar size="mini" :avatar="avatar.image" :name="avatar.name" :tooltip />
|
|
54
54
|
</div>
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { computed } from 'vue'
|
|
3
|
+
import { type Day, day } from '../support/Day'
|
|
3
4
|
|
|
4
|
-
defineProps<{
|
|
5
|
+
const props = defineProps<{
|
|
5
6
|
day?: Day | null
|
|
6
7
|
align?: 'left' | 'center' | 'right'
|
|
7
8
|
format?: string
|
|
8
9
|
color?: 'neutral' | 'soft' | 'mute'
|
|
9
10
|
}>()
|
|
11
|
+
|
|
12
|
+
const formatted = computed(() => {
|
|
13
|
+
if (props.day) {
|
|
14
|
+
return day(props.day).format(props.format ?? 'YYYY-MM-DD HH:mm:ss')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return null
|
|
18
|
+
})
|
|
10
19
|
</script>
|
|
11
20
|
|
|
12
21
|
<template>
|
|
13
22
|
<div class="STableCellDay" :class="[align ?? 'left', color ?? 'neutral']">
|
|
14
|
-
<div v-if="
|
|
15
|
-
{{ day.format(format ?? 'YYYY-MM-DD HH:mm:ss') }}
|
|
16
|
-
</div>
|
|
23
|
+
<div v-if="formatted" class="value">{{ formatted }}</div>
|
|
17
24
|
</div>
|
|
18
25
|
</template>
|
|
19
26
|
|
|
@@ -17,7 +17,6 @@ const props = defineProps<{
|
|
|
17
17
|
onClick?(value: any, record: any): void
|
|
18
18
|
}>()
|
|
19
19
|
|
|
20
|
-
const _value = computed(() => props.number ?? props.value)
|
|
21
20
|
const _color = computed(() => props.color ?? 'neutral')
|
|
22
21
|
const _iconColor = computed(() => props.iconColor ?? _color.value)
|
|
23
22
|
|
|
@@ -31,7 +30,7 @@ const classes = computed(() => [
|
|
|
31
30
|
<template>
|
|
32
31
|
<div class="STableCellNumber" :class="classes">
|
|
33
32
|
<SLink
|
|
34
|
-
v-if="
|
|
33
|
+
v-if="number != null"
|
|
35
34
|
class="container"
|
|
36
35
|
:href="link"
|
|
37
36
|
:role="onClick ? 'button' : null"
|
|
@@ -41,7 +40,7 @@ const classes = computed(() => [
|
|
|
41
40
|
<component :is="icon" class="svg" />
|
|
42
41
|
</div>
|
|
43
42
|
<div class="value" :class="_color">
|
|
44
|
-
{{ separator ? format(
|
|
43
|
+
{{ separator ? format(number) : number }}
|
|
45
44
|
</div>
|
|
46
45
|
</SLink>
|
|
47
46
|
</div>
|
|
@@ -16,8 +16,8 @@ function classes(item: TableCellPathSegment) {
|
|
|
16
16
|
|
|
17
17
|
<template>
|
|
18
18
|
<div class="STableCellPath">
|
|
19
|
-
<template v-for="segment,
|
|
20
|
-
<div v-if="
|
|
19
|
+
<template v-for="(segment, i) in segments" :key="i">
|
|
20
|
+
<div v-if="i > 0" class="divider">/</div>
|
|
21
21
|
<SLink
|
|
22
22
|
class="text"
|
|
23
23
|
:class="classes(segment)"
|
|
@@ -15,7 +15,6 @@ const props = defineProps<{
|
|
|
15
15
|
onClick?(value: any, record: any): void
|
|
16
16
|
}>()
|
|
17
17
|
|
|
18
|
-
const _value = computed(() => props.text ?? props.value)
|
|
19
18
|
const _color = computed(() => props.color ?? 'neutral')
|
|
20
19
|
const _iconColor = computed(() => props.iconColor ?? _color.value)
|
|
21
20
|
|
|
@@ -29,7 +28,7 @@ const classes = computed(() => [
|
|
|
29
28
|
<template>
|
|
30
29
|
<div class="STableCellText" :class="classes">
|
|
31
30
|
<SLink
|
|
32
|
-
v-if="
|
|
31
|
+
v-if="text != null"
|
|
33
32
|
class="container"
|
|
34
33
|
:href="link"
|
|
35
34
|
:role="onClick ? 'button' : null"
|
|
@@ -39,7 +38,7 @@ const classes = computed(() => [
|
|
|
39
38
|
<component :is="icon" class="svg" />
|
|
40
39
|
</div>
|
|
41
40
|
<div class="text" :class="_color">
|
|
42
|
-
{{
|
|
41
|
+
{{ text }}
|
|
43
42
|
</div>
|
|
44
43
|
</SLink>
|
|
45
44
|
</div>
|
|
@@ -17,13 +17,16 @@ const props = withDefaults(defineProps<{
|
|
|
17
17
|
})
|
|
18
18
|
|
|
19
19
|
const emit = defineEmits<{
|
|
20
|
-
resize: [
|
|
20
|
+
'resize-start': [data: { columnName: string; startX: number; initialX: number }]
|
|
21
|
+
'resize-move': [data: { deltaX: number }]
|
|
22
|
+
'resize-end': [data: { columnName: string; finalWidth: string }]
|
|
21
23
|
}>()
|
|
22
24
|
|
|
23
25
|
const { container, isOpen, toggle } = useFlyout()
|
|
24
26
|
|
|
25
27
|
let startWidth = 0
|
|
26
28
|
let startPoint = 0
|
|
29
|
+
let originalUserSelect = ''; let originalPointerEvents = ''
|
|
27
30
|
|
|
28
31
|
const column = ref<HTMLElement | null>(null)
|
|
29
32
|
const dialog = ref<HTMLElement | null>(null)
|
|
@@ -67,24 +70,43 @@ watch(isOpen, (value) => {
|
|
|
67
70
|
value ? adjustDialogPosition() : stopDialogPositionListener()
|
|
68
71
|
})
|
|
69
72
|
|
|
70
|
-
function grip(e:
|
|
73
|
+
function grip(e: MouseEvent) {
|
|
71
74
|
startWidth = column.value?.offsetWidth ?? 0
|
|
72
75
|
startPoint = e.pageX
|
|
73
76
|
|
|
77
|
+
emit('resize-start', {
|
|
78
|
+
columnName: props.name,
|
|
79
|
+
startX: e.pageX,
|
|
80
|
+
initialX: e.pageX
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
originalUserSelect = document.body.style.userSelect
|
|
84
|
+
originalPointerEvents = document.body.style.pointerEvents
|
|
85
|
+
document.body.style.userSelect = 'none'
|
|
86
|
+
document.body.style.pointerEvents = 'none'
|
|
74
87
|
document.addEventListener('mousemove', resize)
|
|
75
88
|
document.addEventListener('mouseup', stopResizeListener)
|
|
76
89
|
}
|
|
77
90
|
|
|
78
91
|
function resize(e: MouseEvent) {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
emit('resize', resized > -1 ? `${resized}px` : 'var(--table-col-width)')
|
|
92
|
+
const deltaX = e.pageX - startPoint
|
|
93
|
+
emit('resize-move', { deltaX })
|
|
83
94
|
}
|
|
84
95
|
|
|
85
|
-
function stopResizeListener() {
|
|
96
|
+
function stopResizeListener(e: MouseEvent) {
|
|
86
97
|
document.removeEventListener('mousemove', resize)
|
|
87
98
|
document.removeEventListener('mouseup', stopResizeListener)
|
|
99
|
+
document.body.style.userSelect = originalUserSelect
|
|
100
|
+
document.body.style.pointerEvents = originalPointerEvents
|
|
101
|
+
|
|
102
|
+
const movedWidth = e.pageX - startPoint
|
|
103
|
+
const resized = startWidth + movedWidth
|
|
104
|
+
const finalWidth = resized > -1 ? `${resized}px` : 'var(--table-col-width)'
|
|
105
|
+
|
|
106
|
+
emit('resize-end', {
|
|
107
|
+
columnName: props.name,
|
|
108
|
+
finalWidth
|
|
109
|
+
})
|
|
88
110
|
}
|
|
89
111
|
|
|
90
112
|
async function adjustDialogPosition() {
|
|
@@ -99,14 +121,13 @@ async function adjustDialogPosition() {
|
|
|
99
121
|
await nextTick()
|
|
100
122
|
|
|
101
123
|
const dialogWidth = dialog.value?.offsetWidth ?? 0
|
|
102
|
-
const position =
|
|
124
|
+
const position = window.innerWidth - rect.right > dialogWidth ? 'right' : 'left'
|
|
103
125
|
|
|
104
126
|
top.value = `${rect.top + rect.height - 8}px`
|
|
105
|
-
left.value
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
)}px`
|
|
127
|
+
left.value = `${Math.max(
|
|
128
|
+
16,
|
|
129
|
+
position === 'right' ? rect.left - 4 : rect.right - dialogWidth - 4
|
|
130
|
+
)}px`
|
|
110
131
|
}
|
|
111
132
|
|
|
112
133
|
function startDialogPositionListener() {
|
|
@@ -121,24 +142,25 @@ function stopDialogPositionListener() {
|
|
|
121
142
|
</script>
|
|
122
143
|
|
|
123
144
|
<template>
|
|
124
|
-
<div class="STableColumn STableCell" :class="classes"
|
|
145
|
+
<div ref="column" class="STableColumn STableCell" :class="classes">
|
|
125
146
|
<div class="container">
|
|
126
147
|
<slot>
|
|
127
148
|
<p class="label">{{ label }}</p>
|
|
128
149
|
|
|
129
|
-
<div v-if="dropdown"
|
|
150
|
+
<div v-if="dropdown" ref="container" class="action">
|
|
130
151
|
<button class="button" :class="{ active: buttonActive }" @click="toggle">
|
|
131
152
|
<IconDotsThree class="icon" />
|
|
132
153
|
</button>
|
|
133
154
|
|
|
134
155
|
<transition name="fade">
|
|
135
|
-
<div v-if="isOpen" class="dialog" :style="{ top, left }"
|
|
156
|
+
<div v-if="isOpen" ref="dialog" class="dialog" :style="{ top, left }">
|
|
136
157
|
<SDropdown :sections="dropdown" />
|
|
137
158
|
</div>
|
|
138
159
|
</transition>
|
|
139
160
|
</div>
|
|
140
161
|
|
|
141
162
|
<div v-if="resizable" class="grip" @mousedown="grip" />
|
|
163
|
+
<div v-if="resizable" class="resize-indicator" />
|
|
142
164
|
</slot>
|
|
143
165
|
</div>
|
|
144
166
|
</div>
|
|
@@ -42,10 +42,18 @@ const hasNext = computed(() => {
|
|
|
42
42
|
<p class="info">{{ format(from) }}–{{ format(to) }} of {{ format(_total) }}</p>
|
|
43
43
|
|
|
44
44
|
<div v-if="onPrev && onNext" class="actions">
|
|
45
|
-
<button
|
|
45
|
+
<button
|
|
46
|
+
class="button prev"
|
|
47
|
+
:class="{ active: hasPrev }"
|
|
48
|
+
@click="() => hasPrev && onPrev?.()"
|
|
49
|
+
>
|
|
46
50
|
<IconCaretLeft class="icon" />
|
|
47
51
|
</button>
|
|
48
|
-
<button
|
|
52
|
+
<button
|
|
53
|
+
class="button next"
|
|
54
|
+
:class="{ active: hasNext }"
|
|
55
|
+
@click="() => hasNext && onNext?.()"
|
|
56
|
+
>
|
|
49
57
|
<IconCaretRight class="icon" />
|
|
50
58
|
</button>
|
|
51
59
|
</div>
|
|
@@ -9,15 +9,15 @@ const props = defineProps<{
|
|
|
9
9
|
|
|
10
10
|
const normalizedMenu = computed(() => {
|
|
11
11
|
return Array.isArray(props.menu[0])
|
|
12
|
-
? props.menu as TableMenu[][]
|
|
13
|
-
: [props.menu] as TableMenu[][]
|
|
12
|
+
? (props.menu as TableMenu[][])
|
|
13
|
+
: ([props.menu] as TableMenu[][])
|
|
14
14
|
})
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
17
|
<template>
|
|
18
18
|
<div class="STableHeaderMenu">
|
|
19
|
-
<div v-for="items,
|
|
20
|
-
<div v-if="
|
|
19
|
+
<div v-for="(items, i) in normalizedMenu" :key="i" class="group">
|
|
20
|
+
<div v-if="i > 0" class="divider" />
|
|
21
21
|
<div v-for="item in items" :key="item.label" class="item">
|
|
22
22
|
<STableHeaderMenuItem
|
|
23
23
|
:label="item.label"
|
|
@@ -14,7 +14,7 @@ const { container, isOpen, toggle } = useFlyout()
|
|
|
14
14
|
</script>
|
|
15
15
|
|
|
16
16
|
<template>
|
|
17
|
-
<div
|
|
17
|
+
<div ref="container" class="STableHeaderMenuItem">
|
|
18
18
|
<button class="button" :class="[state]" @click="toggle">
|
|
19
19
|
<span class="label">{{ label }}</span>
|
|
20
20
|
<span v-if="state !== 'indicate'" class="caret">
|
|
@@ -97,14 +97,14 @@ onBeforeUnmount(() => {
|
|
|
97
97
|
</script>
|
|
98
98
|
|
|
99
99
|
<template>
|
|
100
|
-
<component
|
|
101
|
-
<component :is="triggerTag"
|
|
100
|
+
<component :is="tag" ref="root" class="STooltip" :class="rootClasses" :tabindex>
|
|
101
|
+
<component :is="triggerTag" ref="trigger" class="trigger">
|
|
102
102
|
<slot />
|
|
103
103
|
</component>
|
|
104
104
|
|
|
105
105
|
<Teleport to="#sefirot-modals">
|
|
106
106
|
<Transition name="fade">
|
|
107
|
-
<div v-show="on" class="container" :class="containerClasses"
|
|
107
|
+
<div v-show="on" ref="content" class="container" :class="containerClasses">
|
|
108
108
|
<div v-if="$slots.text" class="tip"><slot name="text" /></div>
|
|
109
109
|
<div v-else-if="text" class="tip" v-html="text" />
|
|
110
110
|
</div>
|
package/lib/composables/Api.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useHttpConfig } from 'sefirot/stores/HttpConfig'
|
|
2
1
|
import { type Ref, type WatchSource, ref, watch } from 'vue'
|
|
3
2
|
import { Http } from '../http/Http'
|
|
3
|
+
import { useHttpConfig } from '../stores/HttpConfig'
|
|
4
4
|
import { tryOnMounted } from './Utils'
|
|
5
5
|
|
|
6
6
|
export interface Query<Data = any> {
|
package/lib/composables/App.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { type HttpOptions } from '
|
|
2
|
-
import {
|
|
3
|
-
import { type
|
|
4
|
-
import { type HasTheme, useSetupTheme } from './Theme'
|
|
1
|
+
import { type HttpOptions, useHttpConfig } from '../stores/HttpConfig'
|
|
2
|
+
import { type Lang, getBrowserLang, provideLang } from './Lang'
|
|
3
|
+
import { type Theme, useTheme } from './Theme'
|
|
5
4
|
|
|
6
|
-
export interface SetupAppUser
|
|
5
|
+
export interface SetupAppUser {
|
|
6
|
+
lang?: Lang
|
|
7
|
+
theme?: Theme
|
|
8
|
+
}
|
|
7
9
|
|
|
8
10
|
export interface SetupAppOptions {
|
|
9
11
|
http?: HttpOptions
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export function useSetupApp(): (user?: SetupAppUser | null, options?: SetupAppOptions) => void {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const setupHttp = useSetupHttp()
|
|
15
|
+
const theme = useTheme()
|
|
16
|
+
const httpConfig = useHttpConfig()
|
|
16
17
|
|
|
17
18
|
return (user, options) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const lang = user?.lang ?? getBrowserLang()
|
|
20
|
+
provideLang(lang)
|
|
21
|
+
if (user?.theme) { theme.value = user.theme }
|
|
22
|
+
httpConfig.apply({ lang, ...options?.http })
|
|
21
23
|
}
|
|
22
24
|
}
|