@lavalogic/scoria 0.38.10 → 0.38.12
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/README.md +58 -58
- package/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +702 -702
- package/dist/Components/Base/BaseModal.svelte +125 -125
- package/dist/Components/Base/ContextWrapper.svelte +72 -72
- package/dist/Components/Base/Pagination.svelte +198 -198
- package/dist/Components/Base/Snippets.svelte +36 -36
- package/dist/Components/BigRadioSet.svelte +38 -38
- package/dist/Components/Bubble.svelte +101 -101
- package/dist/Components/Button.svelte +209 -209
- package/dist/Components/Checkbox.svelte +86 -86
- package/dist/Components/Contexts/ContextMenu.svelte +164 -164
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
- package/dist/Components/Contexts/ToastContainer.svelte +65 -65
- package/dist/Components/Contexts/Tooltip.svelte +37 -37
- package/dist/Components/DataMatrixIcon.svelte +112 -112
- package/dist/Components/DateInput.svelte +148 -148
- package/dist/Components/DatePicker.svelte +300 -300
- package/dist/Components/DesktopModal.svelte +90 -90
- package/dist/Components/Dial.svelte +204 -204
- package/dist/Components/DimensionInput.svelte +170 -170
- package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
- package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
- package/dist/Components/FileCard.svelte +24 -24
- package/dist/Components/FileUpload.svelte +236 -236
- package/dist/Components/GridInputSet.svelte +29 -29
- package/dist/Components/HorizontalTabGroup.svelte +82 -82
- package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
- package/dist/Components/Icon.svelte +128 -128
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/LoadingAnimation.svelte +29 -29
- package/dist/Components/LoadingModal.svelte +45 -45
- package/dist/Components/LoadingOverlay.svelte +25 -25
- package/dist/Components/Modal.svelte +258 -258
- package/dist/Components/MultiSelect.svelte +220 -220
- package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- package/dist/Components/Nav/ServicesNav.svelte +80 -80
- package/dist/Components/NumberInput.svelte +157 -157
- package/dist/Components/PageHeading.svelte +25 -25
- package/dist/Components/PasswordInput.svelte +88 -88
- package/dist/Components/Portal.svelte +36 -36
- package/dist/Components/QuerySelect.svelte +366 -366
- package/dist/Components/SingleSelect.svelte +250 -250
- package/dist/Components/StepButton.svelte +70 -70
- package/dist/Components/StepForm.svelte +140 -140
- package/dist/Components/Switch.svelte +69 -69
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
- package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Misc/FilterInput.svelte +37 -16
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/TableConfigurationModal.svelte +71 -0
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +225 -0
- package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte.d.ts +26 -0
- package/dist/Components/Table/Misc/UpdateViewOptionsModalProps.d.ts +21 -0
- package/dist/Components/Table/Misc/UpdateViewOptionsModalProps.js +1 -0
- package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +49 -1
- package/dist/Components/Table/Types/Context/TableContext.svelte.js +142 -1
- package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.d.ts +2 -2
- package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.js +20 -2
- package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +9 -1
- package/dist/Components/Table/Types/DataRepository/ILocalDataRepository.d.ts +1 -1
- package/dist/Components/Table/Types/DataRepository/IRemoteDataRepository.d.ts +1 -1
- package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +1 -1
- package/dist/Components/Table/Types/Persistence/DatatableView.d.ts +25 -0
- package/dist/Components/Test/TestContextConsumer.svelte +13 -13
- package/dist/Components/TextArea.svelte +130 -130
- package/dist/Components/TextInput.svelte +176 -176
- package/dist/Components/ThreeStateRadio.svelte +131 -131
- package/dist/Components/Touch/BoolCard.svelte +45 -45
- package/dist/Components/Touch/DateModal.svelte +209 -209
- package/dist/Components/Touch/EditCard.svelte +59 -59
- package/dist/Components/Touch/InfoCard.svelte +31 -31
- package/dist/Components/Touch/InfoTextCard.svelte +28 -28
- package/dist/Components/Touch/ModalExplanation.svelte +17 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
- package/dist/Components/Touch/NumberModal.svelte +79 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
- package/dist/Components/Touch/SummaryCard.svelte +93 -93
- package/dist/Components/Touch/TextAreaModal.svelte +95 -95
- package/dist/Components/Touch/TextModal.svelte +106 -106
- package/dist/Components/Touch/TouchCard.svelte +33 -33
- package/dist/Components/Touch/TouchModal.svelte +274 -274
- package/dist/Components/Touch/UtilityButton.svelte +109 -109
- package/dist/Components/VerticalTabGroup.svelte +79 -79
- package/dist/Components/VerticalTabGroupButton.svelte +58 -58
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Types/Examples/ExampleModal.svelte +35 -35
- package/dist/index.d.ts +1 -1
- package/dist/scss/_basics.scss +12 -12
- package/dist/scss/_colours.scss +134 -134
- package/dist/scss/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/dist/scss/_transitions.scss +8 -8
- package/package.json +1 -1
|
@@ -1,113 +1,113 @@
|
|
|
1
|
-
<svelte:options runes />
|
|
2
|
-
|
|
3
|
-
<script
|
|
4
|
-
lang="ts"
|
|
5
|
-
generics="T extends object, IdType extends Primitive"
|
|
6
|
-
>
|
|
7
|
-
import Checkbox from '../../Checkbox.svelte';
|
|
8
|
-
import DesktopModal from '../../DesktopModal.svelte';
|
|
9
|
-
import { Size } from '../../../Types/Internal/Size.js';
|
|
10
|
-
import { getContext } from 'svelte';
|
|
11
|
-
import { TableContext } from '../Types/Context/TableContext.svelte.js';
|
|
12
|
-
import type { Primitive } from '../Types/Context/TableInitOptions.js';
|
|
13
|
-
import type { ToolboxPanelModalProps } from './ToolboxPanelModalProps.js';
|
|
14
|
-
|
|
15
|
-
let { onclose }: ToolboxPanelModalProps = $props();
|
|
16
|
-
|
|
17
|
-
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
18
|
-
|
|
19
|
-
const onCompactChange = (e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
|
20
|
-
tableContext.setIsCompact(e.currentTarget.checked);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const onSingleClickChange = (e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
|
24
|
-
tableContext.setSingleClickEditing(e.currentTarget.checked);
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const onAlternateRowColoursChange = (
|
|
28
|
-
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
29
|
-
) => {
|
|
30
|
-
tableContext.setAlternateRowColours(e.currentTarget.checked);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const onChangeColourOnHoverChange = (
|
|
34
|
-
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
35
|
-
) => {
|
|
36
|
-
tableContext.setChangeColourOnHover(e.currentTarget.checked);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const onCopyWithHeadersChange = (
|
|
40
|
-
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
41
|
-
) => {
|
|
42
|
-
tableContext.setCopyWithHeaders(e.currentTarget.checked);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const onCommaSeparatedCopyChange = (
|
|
46
|
-
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
47
|
-
) => {
|
|
48
|
-
tableContext.setCommaSeparatedCopy(e.currentTarget.checked);
|
|
49
|
-
};
|
|
50
|
-
</script>
|
|
51
|
-
|
|
52
|
-
<DesktopModal
|
|
53
|
-
headerLabel="Table Settings"
|
|
54
|
-
onclose={() => onclose?.()}
|
|
55
|
-
buttons={[{ label: 'Close', callback: () => onclose?.() }]}
|
|
56
|
-
>
|
|
57
|
-
<div class="flex">
|
|
58
|
-
<div class="column-panel">
|
|
59
|
-
<Checkbox
|
|
60
|
-
label="Compact"
|
|
61
|
-
size={Size.MediumSmall}
|
|
62
|
-
id={`is-compact-${tableContext.tableName}-modal`}
|
|
63
|
-
value={tableContext.isCompact}
|
|
64
|
-
onchange={onCompactChange}
|
|
65
|
-
/>
|
|
66
|
-
<Checkbox
|
|
67
|
-
label="Single Click Editing"
|
|
68
|
-
size={Size.MediumSmall}
|
|
69
|
-
id={`single-click-editing-${tableContext.tableName}-modal`}
|
|
70
|
-
value={tableContext.singleClickEditing}
|
|
71
|
-
onchange={onSingleClickChange}
|
|
72
|
-
/>
|
|
73
|
-
<Checkbox
|
|
74
|
-
label="Alternate Row Colours"
|
|
75
|
-
size={Size.MediumSmall}
|
|
76
|
-
id={`alternate-row-colours-${tableContext.tableName}-modal`}
|
|
77
|
-
value={tableContext.alternateRowColours}
|
|
78
|
-
onchange={onAlternateRowColoursChange}
|
|
79
|
-
/>
|
|
80
|
-
<Checkbox
|
|
81
|
-
label="Change Colour on Hover"
|
|
82
|
-
size={Size.MediumSmall}
|
|
83
|
-
id={`change-colour-on-hover-${tableContext.tableName}-modal`}
|
|
84
|
-
value={tableContext.changeColourOnHover}
|
|
85
|
-
onchange={onChangeColourOnHoverChange}
|
|
86
|
-
/>
|
|
87
|
-
{#if tableContext.allowCopy}
|
|
88
|
-
<Checkbox
|
|
89
|
-
label="Include Headers When Copying"
|
|
90
|
-
size={Size.MediumSmall}
|
|
91
|
-
id={`copy-with-headers-${tableContext.tableName}-modal`}
|
|
92
|
-
value={tableContext.copyWithHeaders}
|
|
93
|
-
onchange={onCopyWithHeadersChange}
|
|
94
|
-
/>
|
|
95
|
-
<Checkbox
|
|
96
|
-
label="Copy as Comma Separated Values"
|
|
97
|
-
size={Size.MediumSmall}
|
|
98
|
-
id={`comma-separated-copy-${tableContext.tableName}-modal`}
|
|
99
|
-
value={tableContext.commaSeparatedCopy}
|
|
100
|
-
onchange={onCommaSeparatedCopyChange}
|
|
101
|
-
/>
|
|
102
|
-
{/if}
|
|
103
|
-
</div>
|
|
104
|
-
</div>
|
|
105
|
-
</DesktopModal>
|
|
106
|
-
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T extends object, IdType extends Primitive"
|
|
6
|
+
>
|
|
7
|
+
import Checkbox from '../../Checkbox.svelte';
|
|
8
|
+
import DesktopModal from '../../DesktopModal.svelte';
|
|
9
|
+
import { Size } from '../../../Types/Internal/Size.js';
|
|
10
|
+
import { getContext } from 'svelte';
|
|
11
|
+
import { TableContext } from '../Types/Context/TableContext.svelte.js';
|
|
12
|
+
import type { Primitive } from '../Types/Context/TableInitOptions.js';
|
|
13
|
+
import type { ToolboxPanelModalProps } from './ToolboxPanelModalProps.js';
|
|
14
|
+
|
|
15
|
+
let { onclose }: ToolboxPanelModalProps = $props();
|
|
16
|
+
|
|
17
|
+
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
18
|
+
|
|
19
|
+
const onCompactChange = (e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
|
20
|
+
tableContext.setIsCompact(e.currentTarget.checked);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const onSingleClickChange = (e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
|
24
|
+
tableContext.setSingleClickEditing(e.currentTarget.checked);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const onAlternateRowColoursChange = (
|
|
28
|
+
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
29
|
+
) => {
|
|
30
|
+
tableContext.setAlternateRowColours(e.currentTarget.checked);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const onChangeColourOnHoverChange = (
|
|
34
|
+
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
35
|
+
) => {
|
|
36
|
+
tableContext.setChangeColourOnHover(e.currentTarget.checked);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const onCopyWithHeadersChange = (
|
|
40
|
+
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
41
|
+
) => {
|
|
42
|
+
tableContext.setCopyWithHeaders(e.currentTarget.checked);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const onCommaSeparatedCopyChange = (
|
|
46
|
+
e: Event & { currentTarget: EventTarget & HTMLInputElement }
|
|
47
|
+
) => {
|
|
48
|
+
tableContext.setCommaSeparatedCopy(e.currentTarget.checked);
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<DesktopModal
|
|
53
|
+
headerLabel="Table Settings"
|
|
54
|
+
onclose={() => onclose?.()}
|
|
55
|
+
buttons={[{ label: 'Close', callback: () => onclose?.() }]}
|
|
56
|
+
>
|
|
57
|
+
<div class="flex">
|
|
58
|
+
<div class="column-panel">
|
|
59
|
+
<Checkbox
|
|
60
|
+
label="Compact"
|
|
61
|
+
size={Size.MediumSmall}
|
|
62
|
+
id={`is-compact-${tableContext.tableName}-modal`}
|
|
63
|
+
value={tableContext.isCompact}
|
|
64
|
+
onchange={onCompactChange}
|
|
65
|
+
/>
|
|
66
|
+
<Checkbox
|
|
67
|
+
label="Single Click Editing"
|
|
68
|
+
size={Size.MediumSmall}
|
|
69
|
+
id={`single-click-editing-${tableContext.tableName}-modal`}
|
|
70
|
+
value={tableContext.singleClickEditing}
|
|
71
|
+
onchange={onSingleClickChange}
|
|
72
|
+
/>
|
|
73
|
+
<Checkbox
|
|
74
|
+
label="Alternate Row Colours"
|
|
75
|
+
size={Size.MediumSmall}
|
|
76
|
+
id={`alternate-row-colours-${tableContext.tableName}-modal`}
|
|
77
|
+
value={tableContext.alternateRowColours}
|
|
78
|
+
onchange={onAlternateRowColoursChange}
|
|
79
|
+
/>
|
|
80
|
+
<Checkbox
|
|
81
|
+
label="Change Colour on Hover"
|
|
82
|
+
size={Size.MediumSmall}
|
|
83
|
+
id={`change-colour-on-hover-${tableContext.tableName}-modal`}
|
|
84
|
+
value={tableContext.changeColourOnHover}
|
|
85
|
+
onchange={onChangeColourOnHoverChange}
|
|
86
|
+
/>
|
|
87
|
+
{#if tableContext.allowCopy}
|
|
88
|
+
<Checkbox
|
|
89
|
+
label="Include Headers When Copying"
|
|
90
|
+
size={Size.MediumSmall}
|
|
91
|
+
id={`copy-with-headers-${tableContext.tableName}-modal`}
|
|
92
|
+
value={tableContext.copyWithHeaders}
|
|
93
|
+
onchange={onCopyWithHeadersChange}
|
|
94
|
+
/>
|
|
95
|
+
<Checkbox
|
|
96
|
+
label="Copy as Comma Separated Values"
|
|
97
|
+
size={Size.MediumSmall}
|
|
98
|
+
id={`comma-separated-copy-${tableContext.tableName}-modal`}
|
|
99
|
+
value={tableContext.commaSeparatedCopy}
|
|
100
|
+
onchange={onCommaSeparatedCopyChange}
|
|
101
|
+
/>
|
|
102
|
+
{/if}
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</DesktopModal>
|
|
106
|
+
|
|
107
107
|
<style>.flex {
|
|
108
108
|
display: flex;
|
|
109
109
|
flex-flow: column nowrap;
|
|
110
110
|
height: 100%;
|
|
111
111
|
width: 100%;
|
|
112
112
|
flex: 1;
|
|
113
|
-
}</style>
|
|
113
|
+
}</style>
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
<svelte:options runes />
|
|
2
|
+
|
|
3
|
+
<script
|
|
4
|
+
lang="ts"
|
|
5
|
+
generics="T extends object, IdType extends Primitive"
|
|
6
|
+
>
|
|
7
|
+
import DesktopModal from '../../DesktopModal.svelte';
|
|
8
|
+
import Icon from '../../Icon.svelte';
|
|
9
|
+
import InfoAlert from '../../InfoAlert.svelte';
|
|
10
|
+
import SingleSelect from '../../SingleSelect.svelte';
|
|
11
|
+
import TextInput from '../../TextInput.svelte';
|
|
12
|
+
import { cssLength } from '../../../Helpers/Helpers.svelte.js';
|
|
13
|
+
import { ColourSet } from '../../../scss/colours.js';
|
|
14
|
+
import type { SelectOption } from '../../../Types/Internal/SelectOption.js';
|
|
15
|
+
import { Size } from '../../../Types/Internal/Size.js';
|
|
16
|
+
import { getContext, onMount } from 'svelte';
|
|
17
|
+
import { TableContext } from '../Types/Context/TableContext.svelte.js';
|
|
18
|
+
import type { Primitive } from '../Types/Context/TableInitOptions.js';
|
|
19
|
+
import type { DatatableViewVisibility } from '../Types/Persistence/DatatableView.js';
|
|
20
|
+
import type { UpdateViewOptionsModalProps } from './UpdateViewOptionsModalProps.js';
|
|
21
|
+
|
|
22
|
+
const { view, onclose, onsaved }: UpdateViewOptionsModalProps = $props();
|
|
23
|
+
|
|
24
|
+
const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
|
|
25
|
+
|
|
26
|
+
// Local form state. Seeded from the view's current values inside
|
|
27
|
+
// `onMount` so the modal opens populated with what's already saved
|
|
28
|
+
// without triggering Svelte's `state_referenced_locally` lint
|
|
29
|
+
// against the prop read; Save diffs against the view's current
|
|
30
|
+
// values to skip a no-op PATCH.
|
|
31
|
+
let name: string = $state('');
|
|
32
|
+
let visibility: DatatableViewVisibility = $state('private');
|
|
33
|
+
|
|
34
|
+
onMount(() => {
|
|
35
|
+
name = view.name;
|
|
36
|
+
visibility = view.visibility ?? 'private';
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// User-visible error banner. Adapter rejections are routed here so
|
|
40
|
+
// the modal never throws into the host UI.
|
|
41
|
+
let errorMessage = $state<string | null>(null);
|
|
42
|
+
|
|
43
|
+
// `true` while the PATCH is in flight, disables the footer buttons.
|
|
44
|
+
let saving = $state(false);
|
|
45
|
+
|
|
46
|
+
const visibilityOptions: Array<SelectOption<DatatableViewVisibility>> = [
|
|
47
|
+
{
|
|
48
|
+
label: 'Private — only owner and explicit subscribers',
|
|
49
|
+
value: 'private',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
label: 'Public — anyone with access to this table can subscribe',
|
|
53
|
+
value: 'public',
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const selectedVisibility: SelectOption<DatatableViewVisibility> = $derived(
|
|
58
|
+
visibilityOptions.find((o) => o.value === visibility) ?? visibilityOptions[0]
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// Whether anything in the form differs from the initial values.
|
|
62
|
+
// Drives the Save button's disabled state so a no-op Save never
|
|
63
|
+
// hits the network (also enforced inside `updateViewOptions`).
|
|
64
|
+
const dirty = $derived(
|
|
65
|
+
name.trim() !== view.name || visibility !== (view.visibility ?? 'private')
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
/** Whether the name is valid for submission (non-empty, trimmed). */
|
|
69
|
+
const isValidName = $derived(name.trim().length > 0);
|
|
70
|
+
|
|
71
|
+
async function save(): Promise<void> {
|
|
72
|
+
if (!dirty) {
|
|
73
|
+
onclose();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!isValidName) {
|
|
77
|
+
errorMessage = `Name cannot be empty.`;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
errorMessage = null;
|
|
82
|
+
saving = true;
|
|
83
|
+
try {
|
|
84
|
+
await tableContext.updateViewOptions(view, {
|
|
85
|
+
name: name.trim(),
|
|
86
|
+
visibility,
|
|
87
|
+
});
|
|
88
|
+
if (onsaved) {
|
|
89
|
+
await onsaved();
|
|
90
|
+
}
|
|
91
|
+
onclose();
|
|
92
|
+
} catch (e: unknown) {
|
|
93
|
+
console.error('[UpdateViewOptionsModal] save failed:', e);
|
|
94
|
+
errorMessage =
|
|
95
|
+
e instanceof Error
|
|
96
|
+
? `Could not update options. (${e.message})`
|
|
97
|
+
: 'Could not update options.';
|
|
98
|
+
} finally {
|
|
99
|
+
saving = false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
</script>
|
|
103
|
+
|
|
104
|
+
<DesktopModal
|
|
105
|
+
headerLabel={`Update Options - "${view.name}"`}
|
|
106
|
+
headerSubtitle={`Rename and change sharing for this ${view.kind === 'filter' ? 'filter' : 'layout'}.`}
|
|
107
|
+
onclose={() => {
|
|
108
|
+
if (!saving) {
|
|
109
|
+
onclose();
|
|
110
|
+
}
|
|
111
|
+
}}
|
|
112
|
+
width={cssLength('40vw')}
|
|
113
|
+
minWidth={cssLength('32rem')}
|
|
114
|
+
buttons={[
|
|
115
|
+
{
|
|
116
|
+
label: 'Cancel',
|
|
117
|
+
callback: () => {
|
|
118
|
+
if (!saving) {
|
|
119
|
+
onclose();
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
disabled: saving,
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
label: saving ? 'Saving…' : 'Save',
|
|
126
|
+
callback: () => {
|
|
127
|
+
void save();
|
|
128
|
+
},
|
|
129
|
+
colourSet: ColourSet.Primary,
|
|
130
|
+
disabled: saving || !dirty || !isValidName,
|
|
131
|
+
},
|
|
132
|
+
]}
|
|
133
|
+
>
|
|
134
|
+
<div class="options-body">
|
|
135
|
+
{#if errorMessage}
|
|
136
|
+
<div
|
|
137
|
+
class="error-banner"
|
|
138
|
+
role="alert"
|
|
139
|
+
>
|
|
140
|
+
<Icon
|
|
141
|
+
name="circle-exclamation"
|
|
142
|
+
size={Size.Small}
|
|
143
|
+
/>
|
|
144
|
+
<span>{errorMessage}</span>
|
|
145
|
+
</div>
|
|
146
|
+
{/if}
|
|
147
|
+
|
|
148
|
+
<InfoAlert>
|
|
149
|
+
Changes apply to every user who has access to this {view.kind === 'filter'
|
|
150
|
+
? 'filter'
|
|
151
|
+
: 'layout'}. Making it public allows any user with access to the table to subscribe.
|
|
152
|
+
</InfoAlert>
|
|
153
|
+
|
|
154
|
+
<div class="field">
|
|
155
|
+
<label
|
|
156
|
+
class="field-label"
|
|
157
|
+
for="update-view-name">Name</label
|
|
158
|
+
>
|
|
159
|
+
<TextInput
|
|
160
|
+
id="update-view-name"
|
|
161
|
+
bind:value={name}
|
|
162
|
+
placeholder={`${view.kind === 'filter' ? 'Filter' : 'Layout'} name`}
|
|
163
|
+
required
|
|
164
|
+
invalid={!isValidName}
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
|
|
168
|
+
<div class="field">
|
|
169
|
+
<label
|
|
170
|
+
class="field-label"
|
|
171
|
+
for="update-view-visibility">Visibility</label
|
|
172
|
+
>
|
|
173
|
+
<SingleSelect
|
|
174
|
+
inputId="update-view-visibility"
|
|
175
|
+
name="Visibility"
|
|
176
|
+
options={visibilityOptions}
|
|
177
|
+
labelProp="label"
|
|
178
|
+
valueProp="value"
|
|
179
|
+
value={selectedVisibility}
|
|
180
|
+
valueAsObject
|
|
181
|
+
searchable={false}
|
|
182
|
+
onchange={(option: SelectOption<DatatableViewVisibility> | null) => {
|
|
183
|
+
if (option) {
|
|
184
|
+
visibility = option.value;
|
|
185
|
+
}
|
|
186
|
+
}}
|
|
187
|
+
/>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</DesktopModal>
|
|
191
|
+
|
|
192
|
+
<style>.options-body {
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-flow: column nowrap;
|
|
195
|
+
gap: 0.75rem;
|
|
196
|
+
padding: 1rem;
|
|
197
|
+
min-height: 25vh;
|
|
198
|
+
max-height: 60vh;
|
|
199
|
+
overflow-y: auto;
|
|
200
|
+
background-color: #ffffff;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.error-banner {
|
|
204
|
+
display: flex;
|
|
205
|
+
flex-flow: row nowrap;
|
|
206
|
+
align-items: center;
|
|
207
|
+
gap: 0.5rem;
|
|
208
|
+
padding: 0.5rem 0.75rem;
|
|
209
|
+
border: solid 1px #aa1414;
|
|
210
|
+
border-radius: 4px;
|
|
211
|
+
background-color: #f9e9e9;
|
|
212
|
+
color: #aa1414;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.field {
|
|
216
|
+
display: flex;
|
|
217
|
+
flex-flow: column nowrap;
|
|
218
|
+
gap: 0.25rem;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.field-label {
|
|
222
|
+
font-size: 1.125rem;
|
|
223
|
+
font-weight: 600;
|
|
224
|
+
color: #3a4952;
|
|
225
|
+
}</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Primitive } from '../Types/Context/TableInitOptions.js';
|
|
2
|
+
import type { UpdateViewOptionsModalProps } from './UpdateViewOptionsModalProps.js';
|
|
3
|
+
declare function $$render<T extends object, IdType extends Primitive>(): {
|
|
4
|
+
props: UpdateViewOptionsModalProps;
|
|
5
|
+
exports: {};
|
|
6
|
+
bindings: "";
|
|
7
|
+
slots: {};
|
|
8
|
+
events: {};
|
|
9
|
+
};
|
|
10
|
+
declare class __sveltets_Render<T extends object, IdType extends Primitive> {
|
|
11
|
+
props(): ReturnType<typeof $$render<T, IdType>>['props'];
|
|
12
|
+
events(): ReturnType<typeof $$render<T, IdType>>['events'];
|
|
13
|
+
slots(): ReturnType<typeof $$render<T, IdType>>['slots'];
|
|
14
|
+
bindings(): "";
|
|
15
|
+
exports(): {};
|
|
16
|
+
}
|
|
17
|
+
interface $$IsomorphicComponent {
|
|
18
|
+
new <T extends object, IdType extends Primitive>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T, IdType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T, IdType>['props']>, ReturnType<__sveltets_Render<T, IdType>['events']>, ReturnType<__sveltets_Render<T, IdType>['slots']>> & {
|
|
19
|
+
$$bindings?: ReturnType<__sveltets_Render<T, IdType>['bindings']>;
|
|
20
|
+
} & ReturnType<__sveltets_Render<T, IdType>['exports']>;
|
|
21
|
+
<T extends object, IdType extends Primitive>(internal: unknown, props: ReturnType<__sveltets_Render<T, IdType>['props']> & {}): ReturnType<__sveltets_Render<T, IdType>['exports']>;
|
|
22
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
23
|
+
}
|
|
24
|
+
declare const UpdateViewOptionsModal: $$IsomorphicComponent;
|
|
25
|
+
type UpdateViewOptionsModal<T extends object, IdType extends Primitive> = InstanceType<typeof UpdateViewOptionsModal<T, IdType>>;
|
|
26
|
+
export default UpdateViewOptionsModal;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DatatableView } from '../Types/Persistence/DatatableView.js';
|
|
2
|
+
/**
|
|
3
|
+
* Props for `UpdateViewOptionsModal` - the FPM 403 round-6 dialog
|
|
4
|
+
* opened from a saved view card's "Update Options" button. The modal
|
|
5
|
+
* lets the user rename the view and toggle its sharing visibility
|
|
6
|
+
* (`'private'` / `'public'`); Save patches both fields in one call
|
|
7
|
+
* through `TableContext.updateViewOptions`.
|
|
8
|
+
*/
|
|
9
|
+
export interface UpdateViewOptionsModalProps {
|
|
10
|
+
/** The saved view being edited. Its current `name` / `visibility`
|
|
11
|
+
* pre-populate the form; `id` + `kind` are forwarded to the
|
|
12
|
+
* update call. */
|
|
13
|
+
view: DatatableView;
|
|
14
|
+
/** Called when the modal should close - both on Cancel and after
|
|
15
|
+
* a successful Save. */
|
|
16
|
+
onclose: () => void;
|
|
17
|
+
/** Called after a successful Save, before `onclose`. The host
|
|
18
|
+
* wires this to a saved-views refresh so the My-* card label
|
|
19
|
+
* reflects the new name. Optional - omit to skip the refresh. */
|
|
20
|
+
onsaved?: () => void | Promise<void>;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -13,7 +13,7 @@ import type { VisibilityState } from '../Columns/VisibilityState.js';
|
|
|
13
13
|
import type { CellCoordinates } from '../Coordinates/CellCoordinates.js';
|
|
14
14
|
import type { VisualColumnIndex } from '../Coordinates/ColumnIndices.js';
|
|
15
15
|
import type { RemoteTableLayoutAdapter } from '../Persistence/RemoteTableLayoutAdapter.js';
|
|
16
|
-
import type { DatatableView } from '../Persistence/DatatableView.js';
|
|
16
|
+
import type { DatatableView, DatatableViewVisibility } from '../Persistence/DatatableView.js';
|
|
17
17
|
import type { DatatableViewKind } from '../Persistence/DatatableViewKind.js';
|
|
18
18
|
import type { IDataRepository } from '../DataRepository/IDataRepository.js';
|
|
19
19
|
import { SortingState } from './SortingState.svelte.js';
|
|
@@ -943,6 +943,54 @@ export declare class TableContext<T extends object, RowIdType extends Primitive>
|
|
|
943
943
|
* disabled. An adapter rejection is routed to `devCatch`.
|
|
944
944
|
*/
|
|
945
945
|
readonly saveActiveView: (kind: DatatableViewKind) => Promise<void>;
|
|
946
|
+
/**
|
|
947
|
+
* Save the live state of the table INTO an arbitrary saved view,
|
|
948
|
+
* overwriting that view's stored body. Unlike `saveActiveView` -
|
|
949
|
+
* which only works when the target IS the kind's active view -
|
|
950
|
+
* this accepts any saved view: a "Save Layout" / "Save Filter"
|
|
951
|
+
* button on a card can overwrite the saved view with the user's
|
|
952
|
+
* current tweaks regardless of what the active view is.
|
|
953
|
+
*
|
|
954
|
+
* Flow:
|
|
955
|
+
*
|
|
956
|
+
* 1. capture the live layout / filter (chosen by `view.kind`);
|
|
957
|
+
* 2. `await remoteLayouts.updateView({ id, body })`;
|
|
958
|
+
* 3. swap the matching entry in that kind's saved-views list with
|
|
959
|
+
* the authoritative server return;
|
|
960
|
+
* 4. if the just-saved view IS the kind's currently active view,
|
|
961
|
+
* repoint that kind's baseline at the new body and clear the
|
|
962
|
+
* dirty flag - the dropdown immediately reads "<name>" instead
|
|
963
|
+
* of "<name> (unsaved)".
|
|
964
|
+
*
|
|
965
|
+
* No-op (dev-logged) when remote saved views are disabled. Adapter
|
|
966
|
+
* rejections are re-thrown so the caller can surface them in the
|
|
967
|
+
* Table Configuration modal's inline error banner.
|
|
968
|
+
*/
|
|
969
|
+
readonly saveLiveStateIntoView: (view: DatatableView) => Promise<void>;
|
|
970
|
+
/**
|
|
971
|
+
* Update a saved view's options - currently its `name` and
|
|
972
|
+
* `visibility`. The view's body is left untouched (use
|
|
973
|
+
* `saveLiveStateIntoView` or `saveActiveView` for that). Driven by
|
|
974
|
+
* the "Update Options" modal on each My-* card.
|
|
975
|
+
*
|
|
976
|
+
* Flow:
|
|
977
|
+
*
|
|
978
|
+
* 1. `await remoteLayouts.updateView({ id, name?, visibility? })`;
|
|
979
|
+
* 2. swap the matching entry in that kind's saved-views list with
|
|
980
|
+
* the authoritative server return so the new name / visibility
|
|
981
|
+
* are reflected in every reactive surface;
|
|
982
|
+
* 3. if the renamed view IS the kind's currently active view, push
|
|
983
|
+
* the new name onto the active-view ref so the quick-switch
|
|
984
|
+
* dropdown and "active view" label update immediately.
|
|
985
|
+
*
|
|
986
|
+
* No-op (dev-logged) when remote saved views are disabled. Adapter
|
|
987
|
+
* rejections are re-thrown so the caller can surface them in the
|
|
988
|
+
* modal.
|
|
989
|
+
*/
|
|
990
|
+
readonly updateViewOptions: (view: DatatableView, options: {
|
|
991
|
+
name?: string;
|
|
992
|
+
visibility?: DatatableViewVisibility;
|
|
993
|
+
}) => Promise<void>;
|
|
946
994
|
/**
|
|
947
995
|
* Fetch the saved views for this datatable through the injected
|
|
948
996
|
* `remoteLayouts` adapter and publish them into `_viewState`, split by
|