@genspectrum/dashboard-components 0.11.2 → 0.11.3
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/dist/assets/mutationOverTimeWorker-Cr-NmYEs.js.map +1 -1
- package/dist/components.d.ts +44 -44
- package/dist/components.js +143 -148
- package/dist/components.js.map +1 -1
- package/dist/style.css +0 -10
- package/dist/util.d.ts +44 -44
- package/package.json +1 -1
- package/src/preact/components/error-display.tsx +11 -16
- package/src/preact/components/info.tsx +5 -19
- package/src/preact/components/modal.stories.tsx +44 -0
- package/src/preact/components/modal.tsx +31 -0
- package/src/preact/map/sequences-by-location-map.tsx +24 -33
- package/standalone-bundle/assets/mutationOverTimeWorker-DIQRmxvC.js.map +1 -1
- package/standalone-bundle/dashboard-components.js +2958 -2955
- package/standalone-bundle/dashboard-components.js.map +1 -1
- package/standalone-bundle/style.css +1 -1
package/dist/style.css
CHANGED
|
@@ -2684,9 +2684,6 @@ input.tab:checked + .tab-content,
|
|
|
2684
2684
|
border-end-end-radius: inherit;
|
|
2685
2685
|
border-start-end-radius: inherit;
|
|
2686
2686
|
}
|
|
2687
|
-
.modal-middle {
|
|
2688
|
-
place-items: center;
|
|
2689
|
-
}
|
|
2690
2687
|
.modal-bottom {
|
|
2691
2688
|
place-items: end;
|
|
2692
2689
|
}
|
|
@@ -3131,9 +3128,6 @@ input.tab:checked + .tab-content,
|
|
|
3131
3128
|
.min-w-\[7\.5rem\] {
|
|
3132
3129
|
min-width: 7.5rem;
|
|
3133
3130
|
}
|
|
3134
|
-
.max-w-3xl {
|
|
3135
|
-
max-width: 48rem;
|
|
3136
|
-
}
|
|
3137
3131
|
.max-w-screen-lg {
|
|
3138
3132
|
max-width: 1024px;
|
|
3139
3133
|
}
|
|
@@ -3307,10 +3301,6 @@ input.tab:checked + .tab-content,
|
|
|
3307
3301
|
padding-top: 0.5rem;
|
|
3308
3302
|
padding-bottom: 0.5rem;
|
|
3309
3303
|
}
|
|
3310
|
-
.py-4 {
|
|
3311
|
-
padding-top: 1rem;
|
|
3312
|
-
padding-bottom: 1rem;
|
|
3313
|
-
}
|
|
3314
3304
|
.pl-2 {
|
|
3315
3305
|
padding-left: 0.5rem;
|
|
3316
3306
|
}
|
package/dist/util.d.ts
CHANGED
|
@@ -787,7 +787,10 @@ declare global {
|
|
|
787
787
|
|
|
788
788
|
declare global {
|
|
789
789
|
interface HTMLElementTagNameMap {
|
|
790
|
-
'gs-
|
|
790
|
+
'gs-location-filter': LocationFilterComponent;
|
|
791
|
+
}
|
|
792
|
+
interface HTMLElementEventMap {
|
|
793
|
+
'gs-location-changed': CustomEvent<Record<string, string>>;
|
|
791
794
|
}
|
|
792
795
|
}
|
|
793
796
|
|
|
@@ -795,7 +798,7 @@ declare global {
|
|
|
795
798
|
declare global {
|
|
796
799
|
namespace JSX {
|
|
797
800
|
interface IntrinsicElements {
|
|
798
|
-
'gs-
|
|
801
|
+
'gs-location-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
799
802
|
}
|
|
800
803
|
}
|
|
801
804
|
}
|
|
@@ -803,7 +806,11 @@ declare global {
|
|
|
803
806
|
|
|
804
807
|
declare global {
|
|
805
808
|
interface HTMLElementTagNameMap {
|
|
806
|
-
'gs-
|
|
809
|
+
'gs-date-range-selector': DateRangeSelectorComponent;
|
|
810
|
+
}
|
|
811
|
+
interface HTMLElementEventMap {
|
|
812
|
+
'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
|
|
813
|
+
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
807
814
|
}
|
|
808
815
|
}
|
|
809
816
|
|
|
@@ -811,7 +818,7 @@ declare global {
|
|
|
811
818
|
declare global {
|
|
812
819
|
namespace JSX {
|
|
813
820
|
interface IntrinsicElements {
|
|
814
|
-
'gs-
|
|
821
|
+
'gs-date-range-selector': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
815
822
|
}
|
|
816
823
|
}
|
|
817
824
|
}
|
|
@@ -819,7 +826,10 @@ declare global {
|
|
|
819
826
|
|
|
820
827
|
declare global {
|
|
821
828
|
interface HTMLElementTagNameMap {
|
|
822
|
-
'gs-
|
|
829
|
+
'gs-text-input': TextInputComponent;
|
|
830
|
+
}
|
|
831
|
+
interface HTMLElementEventMap {
|
|
832
|
+
'gs-text-input-changed': CustomEvent<Record<string, string>>;
|
|
823
833
|
}
|
|
824
834
|
}
|
|
825
835
|
|
|
@@ -827,7 +837,7 @@ declare global {
|
|
|
827
837
|
declare global {
|
|
828
838
|
namespace JSX {
|
|
829
839
|
interface IntrinsicElements {
|
|
830
|
-
'gs-
|
|
840
|
+
'gs-text-input': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
831
841
|
}
|
|
832
842
|
}
|
|
833
843
|
}
|
|
@@ -835,7 +845,10 @@ declare global {
|
|
|
835
845
|
|
|
836
846
|
declare global {
|
|
837
847
|
interface HTMLElementTagNameMap {
|
|
838
|
-
'gs-
|
|
848
|
+
'gs-mutation-filter': MutationFilterComponent;
|
|
849
|
+
}
|
|
850
|
+
interface HTMLElementEventMap {
|
|
851
|
+
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
839
852
|
}
|
|
840
853
|
}
|
|
841
854
|
|
|
@@ -843,7 +856,7 @@ declare global {
|
|
|
843
856
|
declare global {
|
|
844
857
|
namespace JSX {
|
|
845
858
|
interface IntrinsicElements {
|
|
846
|
-
'gs-
|
|
859
|
+
'gs-mutation-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
847
860
|
}
|
|
848
861
|
}
|
|
849
862
|
}
|
|
@@ -851,7 +864,10 @@ declare global {
|
|
|
851
864
|
|
|
852
865
|
declare global {
|
|
853
866
|
interface HTMLElementTagNameMap {
|
|
854
|
-
'gs-
|
|
867
|
+
'gs-lineage-filter': LineageFilterComponent;
|
|
868
|
+
}
|
|
869
|
+
interface HTMLElementEventMap {
|
|
870
|
+
'gs-lineage-filter-changed': CustomEvent<Record<string, string>>;
|
|
855
871
|
}
|
|
856
872
|
}
|
|
857
873
|
|
|
@@ -859,7 +875,7 @@ declare global {
|
|
|
859
875
|
declare global {
|
|
860
876
|
namespace JSX {
|
|
861
877
|
interface IntrinsicElements {
|
|
862
|
-
'gs-
|
|
878
|
+
'gs-lineage-filter': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
863
879
|
}
|
|
864
880
|
}
|
|
865
881
|
}
|
|
@@ -867,7 +883,7 @@ declare global {
|
|
|
867
883
|
|
|
868
884
|
declare global {
|
|
869
885
|
interface HTMLElementTagNameMap {
|
|
870
|
-
'gs-
|
|
886
|
+
'gs-mutation-comparison-component': MutationComparisonComponent;
|
|
871
887
|
}
|
|
872
888
|
}
|
|
873
889
|
|
|
@@ -875,7 +891,7 @@ declare global {
|
|
|
875
891
|
declare global {
|
|
876
892
|
namespace JSX {
|
|
877
893
|
interface IntrinsicElements {
|
|
878
|
-
'gs-
|
|
894
|
+
'gs-mutation-comparison-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
879
895
|
}
|
|
880
896
|
}
|
|
881
897
|
}
|
|
@@ -883,7 +899,7 @@ declare global {
|
|
|
883
899
|
|
|
884
900
|
declare global {
|
|
885
901
|
interface HTMLElementTagNameMap {
|
|
886
|
-
'gs-mutations-
|
|
902
|
+
'gs-mutations-component': MutationsComponent;
|
|
887
903
|
}
|
|
888
904
|
}
|
|
889
905
|
|
|
@@ -891,7 +907,7 @@ declare global {
|
|
|
891
907
|
declare global {
|
|
892
908
|
namespace JSX {
|
|
893
909
|
interface IntrinsicElements {
|
|
894
|
-
'gs-mutations-
|
|
910
|
+
'gs-mutations-component': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
895
911
|
}
|
|
896
912
|
}
|
|
897
913
|
}
|
|
@@ -899,7 +915,7 @@ declare global {
|
|
|
899
915
|
|
|
900
916
|
declare global {
|
|
901
917
|
interface HTMLElementTagNameMap {
|
|
902
|
-
'gs-
|
|
918
|
+
'gs-prevalence-over-time': PrevalenceOverTimeComponent;
|
|
903
919
|
}
|
|
904
920
|
}
|
|
905
921
|
|
|
@@ -907,7 +923,7 @@ declare global {
|
|
|
907
923
|
declare global {
|
|
908
924
|
namespace JSX {
|
|
909
925
|
interface IntrinsicElements {
|
|
910
|
-
'gs-
|
|
926
|
+
'gs-prevalence-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
911
927
|
}
|
|
912
928
|
}
|
|
913
929
|
}
|
|
@@ -915,7 +931,7 @@ declare global {
|
|
|
915
931
|
|
|
916
932
|
declare global {
|
|
917
933
|
interface HTMLElementTagNameMap {
|
|
918
|
-
'gs-
|
|
934
|
+
'gs-relative-growth-advantage': RelativeGrowthAdvantageComponent;
|
|
919
935
|
}
|
|
920
936
|
}
|
|
921
937
|
|
|
@@ -923,7 +939,7 @@ declare global {
|
|
|
923
939
|
declare global {
|
|
924
940
|
namespace JSX {
|
|
925
941
|
interface IntrinsicElements {
|
|
926
|
-
'gs-
|
|
942
|
+
'gs-relative-growth-advantage': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
927
943
|
}
|
|
928
944
|
}
|
|
929
945
|
}
|
|
@@ -931,11 +947,7 @@ declare global {
|
|
|
931
947
|
|
|
932
948
|
declare global {
|
|
933
949
|
interface HTMLElementTagNameMap {
|
|
934
|
-
'gs-
|
|
935
|
-
}
|
|
936
|
-
interface HTMLElementEventMap {
|
|
937
|
-
'gs-date-range-filter-changed': CustomEvent<Record<string, string>>;
|
|
938
|
-
'gs-date-range-option-changed': DateRangeOptionChangedEvent;
|
|
950
|
+
'gs-aggregate': AggregateComponent;
|
|
939
951
|
}
|
|
940
952
|
}
|
|
941
953
|
|
|
@@ -943,7 +955,7 @@ declare global {
|
|
|
943
955
|
declare global {
|
|
944
956
|
namespace JSX {
|
|
945
957
|
interface IntrinsicElements {
|
|
946
|
-
'gs-
|
|
958
|
+
'gs-aggregate': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
947
959
|
}
|
|
948
960
|
}
|
|
949
961
|
}
|
|
@@ -951,10 +963,7 @@ declare global {
|
|
|
951
963
|
|
|
952
964
|
declare global {
|
|
953
965
|
interface HTMLElementTagNameMap {
|
|
954
|
-
'gs-
|
|
955
|
-
}
|
|
956
|
-
interface HTMLElementEventMap {
|
|
957
|
-
'gs-location-changed': CustomEvent<Record<string, string>>;
|
|
966
|
+
'gs-number-sequences-over-time': NumberSequencesOverTimeComponent;
|
|
958
967
|
}
|
|
959
968
|
}
|
|
960
969
|
|
|
@@ -962,7 +971,7 @@ declare global {
|
|
|
962
971
|
declare global {
|
|
963
972
|
namespace JSX {
|
|
964
973
|
interface IntrinsicElements {
|
|
965
|
-
'gs-
|
|
974
|
+
'gs-number-sequences-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
966
975
|
}
|
|
967
976
|
}
|
|
968
977
|
}
|
|
@@ -970,10 +979,7 @@ declare global {
|
|
|
970
979
|
|
|
971
980
|
declare global {
|
|
972
981
|
interface HTMLElementTagNameMap {
|
|
973
|
-
'gs-
|
|
974
|
-
}
|
|
975
|
-
interface HTMLElementEventMap {
|
|
976
|
-
'gs-text-input-changed': CustomEvent<Record<string, string>>;
|
|
982
|
+
'gs-mutations-over-time': MutationsOverTimeComponent;
|
|
977
983
|
}
|
|
978
984
|
}
|
|
979
985
|
|
|
@@ -981,7 +987,7 @@ declare global {
|
|
|
981
987
|
declare global {
|
|
982
988
|
namespace JSX {
|
|
983
989
|
interface IntrinsicElements {
|
|
984
|
-
'gs-
|
|
990
|
+
'gs-mutations-over-time': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
985
991
|
}
|
|
986
992
|
}
|
|
987
993
|
}
|
|
@@ -989,10 +995,7 @@ declare global {
|
|
|
989
995
|
|
|
990
996
|
declare global {
|
|
991
997
|
interface HTMLElementTagNameMap {
|
|
992
|
-
'gs-
|
|
993
|
-
}
|
|
994
|
-
interface HTMLElementEventMap {
|
|
995
|
-
'gs-mutation-filter-changed': CustomEvent<MutationsFilter>;
|
|
998
|
+
'gs-sequences-by-location': SequencesByLocationComponent;
|
|
996
999
|
}
|
|
997
1000
|
}
|
|
998
1001
|
|
|
@@ -1000,7 +1003,7 @@ declare global {
|
|
|
1000
1003
|
declare global {
|
|
1001
1004
|
namespace JSX {
|
|
1002
1005
|
interface IntrinsicElements {
|
|
1003
|
-
'gs-
|
|
1006
|
+
'gs-sequences-by-location': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1004
1007
|
}
|
|
1005
1008
|
}
|
|
1006
1009
|
}
|
|
@@ -1008,10 +1011,7 @@ declare global {
|
|
|
1008
1011
|
|
|
1009
1012
|
declare global {
|
|
1010
1013
|
interface HTMLElementTagNameMap {
|
|
1011
|
-
'gs-
|
|
1012
|
-
}
|
|
1013
|
-
interface HTMLElementEventMap {
|
|
1014
|
-
'gs-lineage-filter-changed': CustomEvent<Record<string, string>>;
|
|
1014
|
+
'gs-statistics': StatisticsComponent;
|
|
1015
1015
|
}
|
|
1016
1016
|
}
|
|
1017
1017
|
|
|
@@ -1019,7 +1019,7 @@ declare global {
|
|
|
1019
1019
|
declare global {
|
|
1020
1020
|
namespace JSX {
|
|
1021
1021
|
interface IntrinsicElements {
|
|
1022
|
-
'gs-
|
|
1022
|
+
'gs-statistics': DetailedHTMLProps<HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
1023
1023
|
}
|
|
1024
1024
|
}
|
|
1025
1025
|
}
|
package/package.json
CHANGED
|
@@ -2,6 +2,8 @@ import { type FunctionComponent } from 'preact';
|
|
|
2
2
|
import { useEffect, useRef } from 'preact/hooks';
|
|
3
3
|
import { type ZodError } from 'zod';
|
|
4
4
|
|
|
5
|
+
import { InfoHeadline1, InfoParagraph } from './info';
|
|
6
|
+
import { Modal, useModalRef } from './modal';
|
|
5
7
|
import { LapisError, UnknownLapisError } from '../../lapisApi/lapisApi';
|
|
6
8
|
|
|
7
9
|
export const GS_ERROR_EVENT_TYPE = 'gs-error';
|
|
@@ -46,7 +48,7 @@ export const ErrorDisplay: FunctionComponent<ErrorDisplayProps> = ({ error, rese
|
|
|
46
48
|
console.error(error);
|
|
47
49
|
|
|
48
50
|
const containerRef = useRef<HTMLInputElement>(null);
|
|
49
|
-
const
|
|
51
|
+
const modalRef = useModalRef();
|
|
50
52
|
|
|
51
53
|
useEffect(() => {
|
|
52
54
|
containerRef.current?.dispatchEvent(new ErrorEvent(error));
|
|
@@ -66,23 +68,16 @@ export const ErrorDisplay: FunctionComponent<ErrorDisplayProps> = ({ error, rese
|
|
|
66
68
|
{details !== undefined && (
|
|
67
69
|
<>
|
|
68
70
|
{' '}
|
|
69
|
-
<button
|
|
71
|
+
<button
|
|
72
|
+
className='underline hover:text-gray-400'
|
|
73
|
+
onClick={() => modalRef.current?.showModal()}
|
|
74
|
+
>
|
|
70
75
|
Show details.
|
|
71
76
|
</button>
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
✕
|
|
77
|
-
</button>
|
|
78
|
-
</form>
|
|
79
|
-
<h1 class='text-lg'>{details.headline}</h1>
|
|
80
|
-
<div class='py-4'>{details.message}</div>
|
|
81
|
-
</div>
|
|
82
|
-
<form method='dialog' class='modal-backdrop'>
|
|
83
|
-
<button>close</button>
|
|
84
|
-
</form>
|
|
85
|
-
</dialog>
|
|
77
|
+
<Modal modalRef={modalRef}>
|
|
78
|
+
<InfoHeadline1>{details.headline}</InfoHeadline1>
|
|
79
|
+
<InfoParagraph>{details.message}</InfoParagraph>
|
|
80
|
+
</Modal>
|
|
86
81
|
</>
|
|
87
82
|
)}
|
|
88
83
|
</div>
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type FunctionComponent } from 'preact';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
import { Modal, useModalRef } from './modal';
|
|
3
4
|
|
|
4
5
|
const Info: FunctionComponent = ({ children }) => {
|
|
5
|
-
const
|
|
6
|
+
const modalRef = useModalRef();
|
|
6
7
|
|
|
7
8
|
const toggleHelp = () => {
|
|
8
|
-
|
|
9
|
+
modalRef.current?.showModal();
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
return (
|
|
@@ -13,22 +14,7 @@ const Info: FunctionComponent = ({ children }) => {
|
|
|
13
14
|
<button type='button' className='btn btn-xs' onClick={toggleHelp}>
|
|
14
15
|
?
|
|
15
16
|
</button>
|
|
16
|
-
<
|
|
17
|
-
<div className='modal-box sm:max-w-5xl'>
|
|
18
|
-
<form method='dialog'>
|
|
19
|
-
<button className='btn btn-sm btn-circle btn-ghost absolute right-2 top-2'>✕</button>
|
|
20
|
-
</form>
|
|
21
|
-
<div className={'flex flex-col'}>{children}</div>
|
|
22
|
-
<div className='modal-action'>
|
|
23
|
-
<form method='dialog'>
|
|
24
|
-
<button className={'float-right underline text-sm hover:text-blue-700 mr-2'}>Close</button>
|
|
25
|
-
</form>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
<form method='dialog' className='modal-backdrop'>
|
|
29
|
-
<button>Helper to close when clicked outside</button>
|
|
30
|
-
</form>
|
|
31
|
-
</dialog>
|
|
17
|
+
<Modal modalRef={modalRef}>{children}</Modal>
|
|
32
18
|
</div>
|
|
33
19
|
);
|
|
34
20
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type Meta, type StoryObj } from '@storybook/preact';
|
|
2
|
+
import { expect, waitFor, within } from '@storybook/test';
|
|
3
|
+
import { type FunctionComponent } from 'preact';
|
|
4
|
+
|
|
5
|
+
import { Modal, type ModalProps, useModalRef } from './modal';
|
|
6
|
+
|
|
7
|
+
const meta: Meta<ModalProps> = {
|
|
8
|
+
title: 'Component/Modal',
|
|
9
|
+
component: Modal,
|
|
10
|
+
parameters: { fetchMock: {} },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default meta;
|
|
14
|
+
|
|
15
|
+
const WrapperWithButtonThatOpensTheModal: FunctionComponent = () => {
|
|
16
|
+
const modalRef = useModalRef();
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div>
|
|
20
|
+
<button className='btn' onClick={() => modalRef.current?.showModal()}>
|
|
21
|
+
Open modal
|
|
22
|
+
</button>
|
|
23
|
+
<Modal modalRef={modalRef}>
|
|
24
|
+
<h1>Modal content</h1>
|
|
25
|
+
</Modal>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const ModalStory: StoryObj<ModalProps> = {
|
|
31
|
+
render: () => {
|
|
32
|
+
return <WrapperWithButtonThatOpensTheModal />;
|
|
33
|
+
},
|
|
34
|
+
play: async ({ canvasElement, step }) => {
|
|
35
|
+
const canvas = within(canvasElement);
|
|
36
|
+
|
|
37
|
+
await step('Open the modal', async () => {
|
|
38
|
+
const button = canvas.getByText('Open modal');
|
|
39
|
+
button.click();
|
|
40
|
+
|
|
41
|
+
await waitFor(() => expect(canvas.getByText('Modal content')).toBeVisible());
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type FunctionComponent, type Ref } from 'preact';
|
|
2
|
+
import { useRef } from 'preact/hooks';
|
|
3
|
+
|
|
4
|
+
export type ModalProps = {
|
|
5
|
+
modalRef: Ref<HTMLDialogElement>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function useModalRef() {
|
|
9
|
+
return useRef<HTMLDialogElement>(null);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const Modal: FunctionComponent<ModalProps> = ({ children, modalRef }) => {
|
|
13
|
+
return (
|
|
14
|
+
<dialog ref={modalRef} className={'modal modal-bottom sm:modal-middle'}>
|
|
15
|
+
<div className='modal-box sm:max-w-5xl'>
|
|
16
|
+
<form method='dialog'>
|
|
17
|
+
<button className='btn btn-sm btn-circle btn-ghost absolute right-2 top-2'>✕</button>
|
|
18
|
+
</form>
|
|
19
|
+
<div className={'flex flex-col'}>{children}</div>
|
|
20
|
+
<div className='modal-action'>
|
|
21
|
+
<form method='dialog'>
|
|
22
|
+
<button className={'float-right underline text-sm hover:text-blue-700 mr-2'}>Close</button>
|
|
23
|
+
</form>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<form method='dialog' className='modal-backdrop'>
|
|
27
|
+
<button>Helper to close when clicked outside</button>
|
|
28
|
+
</form>
|
|
29
|
+
</dialog>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -7,6 +7,7 @@ import { type GeoJsonFeatureProperties, type MapSource, useGeoJsonMap } from './
|
|
|
7
7
|
import { type AggregateData } from '../../query/queryAggregateData';
|
|
8
8
|
import { InfoHeadline1, InfoParagraph } from '../components/info';
|
|
9
9
|
import { LoadingDisplay } from '../components/loading-display';
|
|
10
|
+
import { Modal, useModalRef } from '../components/modal';
|
|
10
11
|
import { formatProportion } from '../shared/table/formatProportion';
|
|
11
12
|
|
|
12
13
|
type FeatureData = { proportion: number; count: number };
|
|
@@ -90,7 +91,7 @@ export const SequencesByLocationMapInner: FunctionComponent<SequencesByLocationM
|
|
|
90
91
|
style: (feature: Feature<GeometryObject, EnhancedGeoJsonFeatureProperties> | undefined) => ({
|
|
91
92
|
fillColor: getColor(feature?.properties.data?.proportion),
|
|
92
93
|
fillOpacity: 1,
|
|
93
|
-
color: '
|
|
94
|
+
color: '#666666',
|
|
94
95
|
weight: 1,
|
|
95
96
|
}),
|
|
96
97
|
})
|
|
@@ -135,48 +136,38 @@ const DataMatchInformation: FunctionComponent<DataMatchInformationProps> = ({
|
|
|
135
136
|
nullCount,
|
|
136
137
|
hasTableView,
|
|
137
138
|
}) => {
|
|
138
|
-
const
|
|
139
|
+
const modalRef = useModalRef();
|
|
139
140
|
|
|
140
141
|
const proportion = formatProportion(countOfMatchedLocationData / totalCount);
|
|
141
142
|
|
|
142
143
|
return (
|
|
143
144
|
<>
|
|
144
145
|
<button
|
|
145
|
-
onClick={() =>
|
|
146
|
+
onClick={() => modalRef.current?.showModal()}
|
|
146
147
|
className='text-sm absolute bottom-0 px-1 z-[1001] bg-white rounded border cursor-pointer tooltip'
|
|
147
148
|
data-tip='Click for detailed information'
|
|
148
149
|
>
|
|
149
150
|
This map shows {proportion} of the data.
|
|
150
151
|
</button>
|
|
151
|
-
<
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
{nullCount
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
<div className='modal-action'>
|
|
171
|
-
<form method='dialog'>
|
|
172
|
-
<button className={'float-right underline text-sm hover:text-blue-700 mr-2'}>Close</button>
|
|
173
|
-
</form>
|
|
174
|
-
</div>
|
|
175
|
-
</div>
|
|
176
|
-
<form method='dialog' className='modal-backdrop'>
|
|
177
|
-
<button>Helper to close when clicked outside</button>
|
|
178
|
-
</form>
|
|
179
|
-
</dialog>
|
|
152
|
+
<Modal modalRef={modalRef}>
|
|
153
|
+
<InfoHeadline1>Sequences By Location - Map View</InfoHeadline1>
|
|
154
|
+
<InfoParagraph>
|
|
155
|
+
The current filter has matched {totalCount.toLocaleString('en-us')} sequences. From these sequences,
|
|
156
|
+
we were able to match {countOfMatchedLocationData.toLocaleString('en-us')} ({proportion}) on
|
|
157
|
+
locations on the map.
|
|
158
|
+
</InfoParagraph>
|
|
159
|
+
<InfoParagraph>
|
|
160
|
+
{unmatchedLocations.length > 0 && (
|
|
161
|
+
<>
|
|
162
|
+
The following locations from the data could not be matched on the map:{' '}
|
|
163
|
+
{unmatchedLocations.map((it) => `"${it}"`).join(', ')}.{' '}
|
|
164
|
+
</>
|
|
165
|
+
)}
|
|
166
|
+
{nullCount > 0 &&
|
|
167
|
+
`${nullCount.toLocaleString('en-us')} matching sequences have no location information. `}
|
|
168
|
+
{hasTableView && 'You can check the table view for more detailed information.'}
|
|
169
|
+
</InfoParagraph>
|
|
170
|
+
</Modal>
|
|
180
171
|
</>
|
|
181
172
|
);
|
|
182
173
|
};
|
|
@@ -232,7 +223,7 @@ function matchLocationDataAndGeoJsonFeatures(
|
|
|
232
223
|
|
|
233
224
|
function getColor(value: number | undefined): string {
|
|
234
225
|
if (value === undefined) {
|
|
235
|
-
return '#
|
|
226
|
+
return '#DDDDDD';
|
|
236
227
|
}
|
|
237
228
|
|
|
238
229
|
const thresholds = [
|