@omnsight/osint-entity-components 0.1.1 → 0.1.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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.1",
6
+ "version": "0.1.3",
7
7
  "engines": {
8
8
  "node": ">=24.0.0"
9
9
  },
@@ -77,6 +77,7 @@
77
77
  "postcss-simple-vars": "^7.0.1",
78
78
  "typescript": "~5.9.3",
79
79
  "typescript-eslint": "^8.57.0",
80
- "vite": "^8.0.1"
80
+ "vite": "^8.0.1",
81
+ "vite-plugin-dts": "^4.5.4"
81
82
  }
82
83
  }
@@ -1,19 +1,8 @@
1
1
  // From: https://icon-sets.iconify.design/mdi/account-tie
2
- import type { SVGProps } from "react";
2
+ import type { SVGProps } from 'react';
3
3
  export const IconMdiAccountTie = ({
4
4
  size = 24,
5
5
  ...props
6
6
  }: SVGProps<SVGSVGElement> & {
7
7
  size?: number | string;
8
- }) => (
9
- <svg
10
- xmlns="http://www.w3.org/2000/svg"
11
- fill="currentColor"
12
- viewBox="0 0 24 24"
13
- width={size}
14
- height={size}
15
- {...props}
16
- >
17
- <path d="M12 3c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m4 10.54c0 1.06-.28 3.53-2.19 6.29L13 15l.94-1.88c-.62-.07-1.27-.12-1.94-.12s-1.32.05-1.94.12L11 15l-.81 4.83C8.28 17.07 8 14.6 8 13.54c-2.39.7-4 1.96-4 3.46v4h16v-4c0-1.5-1.6-2.76-4-3.46" />
18
- </svg>
19
- );
8
+ }) => <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width={size} height={size} {...props}><path d="M12 3c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m4 10.54c0 1.06-.28 3.53-2.19 6.29L13 15l.94-1.88c-.62-.07-1.27-.12-1.94-.12s-1.32.05-1.94.12L11 15l-.81 4.83C8.28 17.07 8 14.6 8 13.54c-2.39.7-4 1.96-4 3.46v4h16v-4c0-1.5-1.6-2.76-4-3.46" /></svg>;
@@ -1,19 +1,8 @@
1
1
  // From: https://icon-sets.iconify.design/mdi/factory
2
- import type { SVGProps } from "react";
2
+ import type { SVGProps } from 'react';
3
3
  export const IconMdiFactory = ({
4
4
  size = 24,
5
5
  ...props
6
6
  }: SVGProps<SVGSVGElement> & {
7
7
  size?: number | string;
8
- }) => (
9
- <svg
10
- xmlns="http://www.w3.org/2000/svg"
11
- fill="currentColor"
12
- viewBox="0 0 24 24"
13
- width={size}
14
- height={size}
15
- {...props}
16
- >
17
- <path d="M4 18v2h4v-2zm0-4v2h10v-2zm6 4v2h4v-2zm6-4v2h4v-2zm0 4v2h4v-2zM2 22V8l5 4V8l5 4V8l5 4 1-10h3l1 10v10z" />
18
- </svg>
19
- );
8
+ }) => <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width={size} height={size} {...props}><path d="M4 18v2h4v-2zm0-4v2h10v-2zm6 4v2h4v-2zm6-4v2h4v-2zm0 4v2h4v-2zM2 22V8l5 4V8l5 4V8l5 4 1-10h3l1 10v10z" /></svg>;
@@ -1,19 +1,8 @@
1
1
  // From: https://icon-sets.iconify.design/mdi/tank
2
- import type { SVGProps } from "react";
2
+ import type { SVGProps } from 'react';
3
3
  export const IconMdiTank = ({
4
4
  size = 24,
5
5
  ...props
6
6
  }: SVGProps<SVGSVGElement> & {
7
7
  size?: number | string;
8
- }) => (
9
- <svg
10
- xmlns="http://www.w3.org/2000/svg"
11
- fill="currentColor"
12
- viewBox="0 0 24 24"
13
- width={size}
14
- height={size}
15
- {...props}
16
- >
17
- <path d="M20 12H4v-1h2l1-5h5l1 5h7zm-6.78-5 .4 2H22V7zM22 16a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3 3 3 0 0 1 3-3h14a3 3 0 0 1 3 3M6 16a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1m7 0a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1m7 0a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1" />
18
- </svg>
19
- );
8
+ }) => <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width={size} height={size} {...props}><path d="M20 12H4v-1h2l1-5h5l1 5h7zm-6.78-5 .4 2H22V7zM22 16a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3 3 3 0 0 1 3-3h14a3 3 0 0 1 3 3M6 16a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1m7 0a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1m7 0a1 1 0 0 0-1-1 1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1" /></svg>;
@@ -1,25 +1,8 @@
1
1
  // From: https://icon-sets.iconify.design/mingcute/government-line
2
- import type { SVGProps } from "react";
2
+ import type { SVGProps } from 'react';
3
3
  export const IconMingcuteGovernmentLine = ({
4
4
  size = 24,
5
5
  ...props
6
6
  }: SVGProps<SVGSVGElement> & {
7
7
  size?: number | string;
8
- }) => (
9
- <svg
10
- xmlns="http://www.w3.org/2000/svg"
11
- fill="currentColor"
12
- viewBox="0 0 24 24"
13
- width={size}
14
- height={size}
15
- {...props}
16
- >
17
- <g fill="none">
18
- <path d="m12.593 23.258-.011.002-.071.035-.02.004-.014-.004-.071-.035q-.016-.005-.024.005l-.004.01-.017.428.005.02.01.013.104.074.015.004.012-.004.104-.074.012-.016.004-.017-.017-.427q-.004-.016-.017-.018m.265-.113-.013.002-.185.093-.01.01-.003.011.018.43.005.012.008.007.201.093q.019.005.029-.008l.004-.014-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014-.034.614q.001.018.017.024l.015-.002.201-.093.01-.008.004-.011.017-.43-.003-.012-.01-.01z" />
19
- <path
20
- fill="currentColor"
21
- d="M21 7a1 1 0 0 1 .117 1.993L21 9v10a1 1 0 0 1 .117 1.993L21 21H3a1 1 0 0 1-.117-1.993L3 19V9a1 1 0 0 1-.117-1.993L3 7zm-2 2H5v10h2v-7a1 1 0 1 1 2 0v7h2v-7a1 1 0 1 1 2 0v7h2v-7a1 1 0 1 1 2 0v7h2zm-1-5a1 1 0 1 1 0 2H6a1 1 0 0 1 0-2z"
22
- />
23
- </g>
24
- </svg>
25
- );
8
+ }) => <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24" width={size} height={size} {...props}><g fill="none"><path d="m12.593 23.258-.011.002-.071.035-.02.004-.014-.004-.071-.035q-.016-.005-.024.005l-.004.01-.017.428.005.02.01.013.104.074.015.004.012-.004.104-.074.012-.016.004-.017-.017-.427q-.004-.016-.017-.018m.265-.113-.013.002-.185.093-.01.01-.003.011.018.43.005.012.008.007.201.093q.019.005.029-.008l.004-.014-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014-.034.614q.001.018.017.024l.015-.002.201-.093.01-.008.004-.011.017-.43-.003-.012-.01-.01z" /><path fill="currentColor" d="M21 7a1 1 0 0 1 .117 1.993L21 9v10a1 1 0 0 1 .117 1.993L21 21H3a1 1 0 0 1-.117-1.993L3 19V9a1 1 0 0 1-.117-1.993L3 7zm-2 2H5v10h2v-7a1 1 0 1 1 2 0v7h2v-7a1 1 0 1 1 2 0v7h2v-7a1 1 0 1 1 2 0v7h2zm-1-5a1 1 0 1 1 0 2H6a1 1 0 0 1 0-2z" /></g></svg>;
@@ -1,9 +1,9 @@
1
- import "@/avatars/layouts/EntityStyles.css";
1
+ import "../avatars/layouts/EntityStyles.css";
2
2
  import { Avatar, Tooltip } from "@mantine/core";
3
3
  import type { Event, Relation } from "omni-osint-crud-client";
4
- import { RelationTooltip } from "@/avatars/layouts/RelationTooltip";
5
- import { EventIcon } from "@/icons";
6
- import { EventCard } from "@/cards";
4
+ import { RelationTooltip } from "./layouts/RelationTooltip";
5
+ import { EventIcon } from "../icons";
6
+ import { EventCard } from "../cards";
7
7
 
8
8
  interface Props {
9
9
  data: Event;
@@ -1,9 +1,9 @@
1
- import "@/avatars/layouts/EntityStyles.css";
1
+ import "../avatars/layouts/EntityStyles.css";
2
2
  import { Avatar, Tooltip } from "@mantine/core";
3
3
  import type { Organization, Relation } from "omni-osint-crud-client";
4
- import { RelationTooltip } from "@/avatars/layouts/RelationTooltip";
5
- import { OrganizationIcon } from "@/icons";
6
- import { OrganizationCard } from "@/cards";
4
+ import { RelationTooltip } from "./layouts/RelationTooltip";
5
+ import { OrganizationIcon } from "../icons";
6
+ import { OrganizationCard } from "../cards";
7
7
 
8
8
  interface Props {
9
9
  data: Organization;
@@ -1,9 +1,9 @@
1
- import "@/avatars/layouts/EntityStyles.css";
1
+ import "../avatars/layouts/EntityStyles.css";
2
2
  import { Avatar, Tooltip } from "@mantine/core";
3
3
  import type { Person, Relation } from "omni-osint-crud-client";
4
- import { RelationTooltip } from "@/avatars/layouts/RelationTooltip";
5
- import { PersonIcon } from "@/icons";
6
- import { PersonCard } from "@/cards";
4
+ import { RelationTooltip } from "./layouts/RelationTooltip";
5
+ import { PersonIcon } from "../icons";
6
+ import { PersonCard } from "../cards";
7
7
 
8
8
  interface Props {
9
9
  data: Person;
@@ -1,9 +1,9 @@
1
- import "@/avatars/layouts/EntityStyles.css";
1
+ import "../avatars/layouts/EntityStyles.css";
2
2
  import { ActionIcon, Avatar, Group, Tooltip, Text } from "@mantine/core";
3
3
  import type { Source, Relation } from "omni-osint-crud-client";
4
- import { RelationTooltip } from "@/avatars/layouts/RelationTooltip";
5
- import { SourceIcon } from "@/icons";
6
- import { SourceCard } from "@/cards";
4
+ import { RelationTooltip } from "./layouts/RelationTooltip";
5
+ import { SourceIcon } from "../icons";
6
+ import { SourceCard } from "../cards";
7
7
 
8
8
  interface Props {
9
9
  data: Source;
@@ -1,9 +1,9 @@
1
- import "@/avatars/layouts/EntityStyles.css";
1
+ import "../avatars/layouts/EntityStyles.css";
2
2
  import { Avatar, Tooltip } from "@mantine/core";
3
3
  import type { Website, Relation } from "omni-osint-crud-client";
4
- import { RelationTooltip } from "@/avatars/layouts/RelationTooltip";
5
- import { WebsiteIcon } from "@/icons";
6
- import { WebsiteCard } from "@/cards";
4
+ import { RelationTooltip } from "./layouts/RelationTooltip";
5
+ import { WebsiteIcon } from "../icons";
6
+ import { WebsiteCard } from "../cards";
7
7
 
8
8
  interface Props {
9
9
  data: Website;
@@ -4,16 +4,45 @@ import { Group, Select, ColorInput } from "@mantine/core";
4
4
  import { ICON_OPTIONS } from "./icons";
5
5
  import { EventIcon } from "./Icon";
6
6
 
7
- interface EventIconSelectProps {
8
- value: Event;
9
- onChange: (value: Event) => void;
7
+ interface EventIconSelectorProps {
8
+ data: Event;
9
+ value?: string | null;
10
+ onChange: (value: string | null) => void;
10
11
  }
11
12
 
12
- export const EventIconSelect: React.FC<EventIconSelectProps> = ({
13
+ export const EventIconSelector: React.FC<EventIconSelectorProps> = ({
14
+ data,
13
15
  value,
14
16
  onChange,
15
17
  }) => {
16
18
  const { t } = useTranslation();
19
+
20
+ const translatedOptions = ICON_OPTIONS.map((option) => ({
21
+ ...option,
22
+ label: t(`event.type.${option.label}`),
23
+ }));
24
+
25
+ return (
26
+ <Select
27
+ leftSection={<EventIcon event={data} />}
28
+ defaultValue={translatedOptions[0].value}
29
+ value={value}
30
+ onChange={onChange}
31
+ data={translatedOptions}
32
+ style={{ flex: 1 }}
33
+ />
34
+ );
35
+ };
36
+
37
+ interface EventColorSelectorProps {
38
+ value?: string | null;
39
+ onChange: (value: string | null) => void;
40
+ }
41
+
42
+ export const EventColorSelector: React.FC<EventColorSelectorProps> = ({
43
+ value,
44
+ onChange,
45
+ }) => {
17
46
  const colors = [
18
47
  "#0089ff",
19
48
  "#ff0000",
@@ -24,37 +53,46 @@ export const EventIconSelect: React.FC<EventIconSelectProps> = ({
24
53
  "#7950f2",
25
54
  ];
26
55
 
56
+ return (
57
+ <ColorInput
58
+ value={value || colors[0]}
59
+ onChange={onChange}
60
+ swatches={colors}
61
+ style={{ flex: 1 }}
62
+ />
63
+ );
64
+ };
65
+
66
+ interface EventIconSelectProps {
67
+ value: Event;
68
+ onChange: (value: Event) => void;
69
+ }
70
+
71
+ export const EventIconSelect: React.FC<EventIconSelectProps> = ({
72
+ value,
73
+ onChange,
74
+ }) => {
27
75
  const handleTypeChange = (type: string | null) => {
28
76
  onChange({ ...value, type: type || undefined });
29
77
  };
30
78
 
31
- const handleColorChange = (color: string) => {
79
+ const handleColorChange = (color: string | null) => {
32
80
  onChange({
33
81
  ...value,
34
82
  attributes: { ...(value.attributes || {}), icon_color: color },
35
83
  });
36
84
  };
37
85
 
38
- const translatedOptions = ICON_OPTIONS.map((option) => ({
39
- ...option,
40
- label: t(`event.type.${option.label}`),
41
- }));
42
-
43
86
  return (
44
87
  <Group>
45
- <Select
46
- leftSection={<EventIcon event={value} />}
47
- defaultValue={translatedOptions[0].value}
88
+ <EventIconSelector
89
+ data={value}
48
90
  value={value.type}
49
91
  onChange={handleTypeChange}
50
- data={translatedOptions}
51
- style={{ flex: 1 }}
52
92
  />
53
- <ColorInput
54
- value={String((value.attributes || {}).icon_color || colors[0])}
93
+ <EventColorSelector
94
+ value={String(value.attributes?.icon_color)}
55
95
  onChange={handleColorChange}
56
- swatches={colors}
57
- style={{ flex: 1 }}
58
96
  />
59
97
  </Group>
60
98
  );
@@ -1,21 +1,21 @@
1
- import { IconMdiHandcuffs } from '@/assets/icons/generated/mdi-handcuffs';
2
- import { IconHugeiconsTradeUp } from '@/assets/icons/generated/hugeicons-trade-up';
3
- import { IconGameIconsPistolGun } from '@/assets/icons/generated/game-icons-pistol-gun';
4
- import { IconIcSharpOilBarrel } from '@/assets/icons/generated/ic-sharp-oil-barrel';
5
- import { IconRiSpyFill } from '@/assets/icons/generated/ri-spy-fill';
6
- import { IconFluentEmojiHighContrastMilitaryHelmet } from '@/assets/icons/generated/fluent-emoji-high-contrast-military-helmet';
7
- import { IconMdiTank } from '@/assets/icons/generated/mdi-tank';
8
- import { IconFaSolidShip } from '@/assets/icons/generated/fa-solid-ship';
9
- import { IconMdiAirplane } from '@/assets/icons/generated/mdi-airplane';
10
- import { IconGameIconsMissileLauncher } from '@/assets/icons/generated/game-icons-missile-launcher';
11
- import { IconGameIconsBombingRun } from '@/assets/icons/generated/game-icons-bombing-run';
12
- import { IconIonTrainSharp } from '@/assets/icons/generated/ion-train-sharp';
13
- import { IconFlowbiteTruckSolid } from '@/assets/icons/generated/flowbite-truck-solid';
14
- import { IconEmojioneMonotoneShip } from '@/assets/icons/generated/emojione-monotone-ship';
15
- import { IconFluentEmojiHighContrastBrokenChain } from '@/assets/icons/generated/fluent-emoji-high-contrast-broken-chain';
16
- import { IconRiExchangeBoxFill } from '@/assets/icons/generated/ri-exchange-box-fill';
17
- import { IconMingcutePhoneCallFill } from '@/assets/icons/generated/mingcute-phone-call-fill';
18
- import { IconBoxiconsAnnouncement } from '@/assets/icons/generated/boxicons-announcement';
1
+ import { IconRiSpyFill } from '../../assets/icons/generated/ri-spy-fill';
2
+ import { IconFluentEmojiHighContrastMilitaryHelmet } from '../../assets/icons/generated/fluent-emoji-high-contrast-military-helmet';
3
+ import { IconMdiTank } from '../../assets/icons/generated/mdi-tank';
4
+ import { IconFaSolidShip } from '../../assets/icons/generated/fa-solid-ship';
5
+ import { IconMdiAirplane } from '../../assets/icons/generated/mdi-airplane';
6
+ import { IconGameIconsMissileLauncher } from '../../assets/icons/generated/game-icons-missile-launcher';
7
+ import { IconGameIconsBombingRun } from '../../assets/icons/generated/game-icons-bombing-run';
8
+ import { IconGameIconsPistolGun } from '../../assets/icons/generated/game-icons-pistol-gun';
9
+ import { IconMdiHandcuffs } from '../../assets/icons/generated/mdi-handcuffs';
10
+ import { IconIonTrainSharp } from '../../assets/icons/generated/ion-train-sharp';
11
+ import { IconFlowbiteTruckSolid } from '../../assets/icons/generated/flowbite-truck-solid';
12
+ import { IconEmojioneMonotoneShip } from '../../assets/icons/generated/emojione-monotone-ship';
13
+ import { IconFluentEmojiHighContrastBrokenChain } from '../../assets/icons/generated/fluent-emoji-high-contrast-broken-chain';
14
+ import { IconHugeiconsTradeUp } from '../../assets/icons/generated/hugeicons-trade-up';
15
+ import { IconIcSharpOilBarrel } from '../../assets/icons/generated/ic-sharp-oil-barrel';
16
+ import { IconRiExchangeBoxFill } from '../../assets/icons/generated/ri-exchange-box-fill';
17
+ import { IconMingcutePhoneCallFill } from '../../assets/icons/generated/mingcute-phone-call-fill';
18
+ import { IconBoxiconsAnnouncement } from '../../assets/icons/generated/boxicons-announcement';
19
19
 
20
20
  interface IconOption {
21
21
  value: string;
@@ -4,16 +4,42 @@ import { Group, Select, ColorInput } from "@mantine/core";
4
4
  import { ICON_OPTIONS } from "./icons";
5
5
  import { OrganizationIcon } from "./Icon";
6
6
 
7
- interface OrganizationIconSelectProps {
8
- value: Organization;
9
- onChange: (value: Organization) => void;
7
+ interface OrganizationIconSelectorProps {
8
+ data: Organization;
9
+ value?: string | null;
10
+ onChange: (value: string | null) => void;
10
11
  }
11
12
 
12
- export const OrganizationIconSelect: React.FC<OrganizationIconSelectProps> = ({
13
- value,
14
- onChange,
15
- }) => {
13
+ export const OrganizationIconSelector: React.FC<
14
+ OrganizationIconSelectorProps
15
+ > = ({ data, value, onChange }) => {
16
16
  const { t } = useTranslation();
17
+
18
+ const translatedOptions = ICON_OPTIONS.map((option) => ({
19
+ ...option,
20
+ label: t(`organization.type.${option.label}`),
21
+ }));
22
+
23
+ return (
24
+ <Select
25
+ leftSection={<OrganizationIcon organization={data} />}
26
+ defaultValue={translatedOptions[0].value}
27
+ value={value}
28
+ onChange={onChange}
29
+ data={translatedOptions}
30
+ style={{ flex: 1 }}
31
+ />
32
+ );
33
+ };
34
+
35
+ interface OrganizationColorSelectorProps {
36
+ value?: string | null;
37
+ onChange: (value: string | null) => void;
38
+ }
39
+
40
+ export const OrganizationColorSelector: React.FC<
41
+ OrganizationColorSelectorProps
42
+ > = ({ value, onChange }) => {
17
43
  const colors = [
18
44
  "#0089ff",
19
45
  "#ff0000",
@@ -24,37 +50,46 @@ export const OrganizationIconSelect: React.FC<OrganizationIconSelectProps> = ({
24
50
  "#7950f2",
25
51
  ];
26
52
 
53
+ return (
54
+ <ColorInput
55
+ value={value || colors[0]}
56
+ onChange={onChange}
57
+ swatches={colors}
58
+ style={{ flex: 1 }}
59
+ />
60
+ );
61
+ };
62
+
63
+ interface OrganizationIconSelectProps {
64
+ value: Organization;
65
+ onChange: (value: Organization) => void;
66
+ }
67
+
68
+ export const OrganizationIconSelect: React.FC<OrganizationIconSelectProps> = ({
69
+ value,
70
+ onChange,
71
+ }) => {
27
72
  const handleTypeChange = (type: string | null) => {
28
73
  onChange({ ...value, type: type || undefined });
29
74
  };
30
75
 
31
- const handleColorChange = (color: string) => {
76
+ const handleColorChange = (color: string | null) => {
32
77
  onChange({
33
78
  ...value,
34
79
  attributes: { ...(value.attributes || {}), icon_color: color },
35
80
  });
36
81
  };
37
82
 
38
- const translatedOptions = ICON_OPTIONS.map((option) => ({
39
- ...option,
40
- label: t(`organization.type.${option.label}`),
41
- }));
42
-
43
83
  return (
44
84
  <Group>
45
- <Select
46
- leftSection={<OrganizationIcon organization={value} />}
47
- defaultValue={translatedOptions[0].value}
85
+ <OrganizationIconSelector
86
+ data={value}
48
87
  value={value.type}
49
88
  onChange={handleTypeChange}
50
- data={translatedOptions}
51
- style={{ flex: 1 }}
52
89
  />
53
- <ColorInput
54
- value={String((value.attributes || {}).icon_color || colors[0])}
90
+ <OrganizationColorSelector
91
+ value={String(value.attributes?.icon_color)}
55
92
  onChange={handleColorChange}
56
- swatches={colors}
57
- style={{ flex: 1 }}
58
93
  />
59
94
  </Group>
60
95
  );
@@ -1,9 +1,10 @@
1
- import { IconRiSeedlingLine } from '@/assets/icons/generated/ri-seedling-line';
2
- import { IconMingcuteGovernmentLine } from '@/assets/icons/generated/mingcute-government-line';
3
- import { IconStreamlineFlexDeepfakeTechnology1Solid } from '@/assets/icons/generated/streamline-flex-deepfake-technology-1-solid';
4
- import { IconPixelTechnology } from '@/assets/icons/generated/pixel-technology';
5
- import { IconMdiFactory } from '@/assets/icons/generated/mdi-factory';
6
- import { IconCodiconOrganization } from '@/assets/icons/generated/codicon-organization';
1
+ import { IconStreamlineFlexDeepfakeTechnology1Solid } from '../../assets/icons/generated/streamline-flex-deepfake-technology-1-solid';
2
+ import { IconPixelTechnology } from '../../assets/icons/generated/pixel-technology';
3
+ import { IconRiSeedlingLine } from '../../assets/icons/generated/ri-seedling-line';
4
+ import { IconMdiFactory } from '../../assets/icons/generated/mdi-factory';
5
+ import { IconCodiconOrganization } from '../../assets/icons/generated/codicon-organization';
6
+ import { IconMingcuteGovernmentLine } from '../../assets/icons/generated/mingcute-government-line';
7
+
7
8
 
8
9
  import { BuildingOfficeIcon } from '@heroicons/react/24/solid';
9
10
 
@@ -4,13 +4,45 @@ import { Group, Select, ColorInput } from '@mantine/core';
4
4
  import { ICON_OPTIONS } from './icons';
5
5
  import { PersonIcon } from './Icon';
6
6
 
7
- interface PersonIconSelectProps {
8
- value: Person;
9
- onChange: (value: Person) => void;
7
+ interface PersonIconSelectorProps {
8
+ data: Person;
9
+ value?: string | null;
10
+ onChange: (value: string | null) => void;
10
11
  }
11
12
 
12
- export const PersonIconSelect: React.FC<PersonIconSelectProps> = ({ value, onChange }) => {
13
+ export const PersonIconSelector: React.FC<PersonIconSelectorProps> = ({
14
+ data,
15
+ value,
16
+ onChange,
17
+ }) => {
13
18
  const { t } = useTranslation();
19
+
20
+ const translatedOptions = ICON_OPTIONS.map((option) => ({
21
+ ...option,
22
+ label: t(`person.type.${option.label}`),
23
+ }));
24
+
25
+ return (
26
+ <Select
27
+ leftSection={<PersonIcon person={data} />}
28
+ defaultValue={translatedOptions[0].value}
29
+ value={value}
30
+ onChange={onChange}
31
+ data={translatedOptions}
32
+ style={{ flex: 1 }}
33
+ />
34
+ );
35
+ };
36
+
37
+ interface PersonColorSelectorProps {
38
+ value?: string | null;
39
+ onChange: (value: string | null) => void;
40
+ }
41
+
42
+ export const PersonColorSelector: React.FC<PersonColorSelectorProps> = ({
43
+ value,
44
+ onChange,
45
+ }) => {
14
46
  const colors = [
15
47
  "#0089ff",
16
48
  "#ff0000",
@@ -21,34 +53,46 @@ export const PersonIconSelect: React.FC<PersonIconSelectProps> = ({ value, onCha
21
53
  "#7950f2",
22
54
  ];
23
55
 
56
+ return (
57
+ <ColorInput
58
+ value={value || colors[0]}
59
+ onChange={onChange}
60
+ swatches={colors}
61
+ style={{ flex: 1 }}
62
+ />
63
+ );
64
+ };
65
+
66
+ interface PersonIconSelectProps {
67
+ value: Person;
68
+ onChange: (value: Person) => void;
69
+ }
70
+
71
+ export const PersonIconSelect: React.FC<PersonIconSelectProps> = ({
72
+ value,
73
+ onChange,
74
+ }) => {
24
75
  const handleTypeChange = (type: string | null) => {
25
76
  onChange({ ...value, type: type || undefined });
26
77
  };
27
78
 
28
- const handleColorChange = (color: string) => {
29
- onChange({ ...value, attributes: { ...(value.attributes || {}), icon_color: color } });
79
+ const handleColorChange = (color: string | null) => {
80
+ onChange({
81
+ ...value,
82
+ attributes: { ...(value.attributes || {}), icon_color: color },
83
+ });
30
84
  };
31
85
 
32
- const translatedOptions = ICON_OPTIONS.map((option) => ({
33
- ...option,
34
- label: t(`person.type.${option.label}`),
35
- }));
36
-
37
86
  return (
38
87
  <Group>
39
- <Select
40
- leftSection={<PersonIcon person={value} />}
41
- defaultValue={translatedOptions[0].value}
88
+ <PersonIconSelector
89
+ data={value}
42
90
  value={value.type}
43
91
  onChange={handleTypeChange}
44
- data={translatedOptions}
45
- style={{ flex: 1 }}
46
92
  />
47
- <ColorInput
48
- value={String((value.attributes || {}).icon_color || colors[0])}
93
+ <PersonColorSelector
94
+ value={String(value.attributes?.icon_color)}
49
95
  onChange={handleColorChange}
50
- swatches={colors}
51
- style={{ flex: 1 }}
52
96
  />
53
97
  </Group>
54
98
  );
@@ -1,6 +1,8 @@
1
- import { IconMdiAccountSchool } from '@/assets/icons/generated/mdi-account-school';
2
- import { IconMdiAccountTieHat } from '@/assets/icons/generated/mdi-account-tie-hat';
3
- import { IconMdiAccountTie } from '@/assets/icons/generated/mdi-account-tie';
1
+ import { IconMdiAccountSchool } from '../../assets/icons/generated/mdi-account-school';
2
+ import { IconMdiAccountTieHat } from '../../assets/icons/generated/mdi-account-tie-hat';
3
+ import { IconMdiAccountTie } from '../../assets/icons/generated/mdi-account-tie';
4
+
5
+
4
6
  interface IconOption {
5
7
  value: string;
6
8
  label: string;
@@ -4,16 +4,45 @@ import { Group, Select, ColorInput } from "@mantine/core";
4
4
  import { ICON_OPTIONS } from "./icons";
5
5
  import { SourceIcon } from "./Icon";
6
6
 
7
- interface SourceIconSelectProps {
8
- value: Source;
9
- onChange: (value: Source) => void;
7
+ interface SourceIconSelectorProps {
8
+ data: Source;
9
+ value?: string | null;
10
+ onChange: (value: string | null) => void;
10
11
  }
11
12
 
12
- export const SourceIconSelect: React.FC<SourceIconSelectProps> = ({
13
+ export const SourceIconSelector: React.FC<SourceIconSelectorProps> = ({
14
+ data,
13
15
  value,
14
16
  onChange,
15
17
  }) => {
16
18
  const { t } = useTranslation();
19
+
20
+ const translatedOptions = ICON_OPTIONS.map((option) => ({
21
+ ...option,
22
+ label: t(`source.type.${option.label}`),
23
+ }));
24
+
25
+ return (
26
+ <Select
27
+ leftSection={<SourceIcon source={data} />}
28
+ defaultValue={translatedOptions[0].value}
29
+ value={value}
30
+ onChange={onChange}
31
+ data={translatedOptions}
32
+ style={{ flex: 1 }}
33
+ />
34
+ );
35
+ };
36
+
37
+ interface SourceColorSelectorProps {
38
+ value?: string | null;
39
+ onChange: (value: string | null) => void;
40
+ }
41
+
42
+ export const SourceColorSelector: React.FC<SourceColorSelectorProps> = ({
43
+ value,
44
+ onChange,
45
+ }) => {
17
46
  const colors = [
18
47
  "#ababab",
19
48
  "#0089ff",
@@ -24,37 +53,46 @@ export const SourceIconSelect: React.FC<SourceIconSelectProps> = ({
24
53
  "#7950f2",
25
54
  ];
26
55
 
56
+ return (
57
+ <ColorInput
58
+ value={value || colors[0]}
59
+ onChange={onChange}
60
+ swatches={colors}
61
+ style={{ flex: 1 }}
62
+ />
63
+ );
64
+ };
65
+
66
+ interface SourceIconSelectProps {
67
+ value: Source;
68
+ onChange: (value: Source) => void;
69
+ }
70
+
71
+ export const SourceIconSelect: React.FC<SourceIconSelectProps> = ({
72
+ value,
73
+ onChange,
74
+ }) => {
27
75
  const handleTypeChange = (type: string | null) => {
28
76
  onChange({ ...value, type: type || undefined });
29
77
  };
30
78
 
31
- const handleColorChange = (color: string) => {
79
+ const handleColorChange = (color: string | null) => {
32
80
  onChange({
33
81
  ...value,
34
82
  attributes: { ...(value.attributes || {}), icon_color: color },
35
83
  });
36
84
  };
37
85
 
38
- const translatedOptions = ICON_OPTIONS.map((option) => ({
39
- ...option,
40
- label: t(`source.type.${option.label}`),
41
- }));
42
-
43
86
  return (
44
87
  <Group>
45
- <Select
46
- leftSection={<SourceIcon source={value} />}
47
- defaultValue={translatedOptions[0].value}
88
+ <SourceIconSelector
89
+ data={value}
48
90
  value={value.type}
49
91
  onChange={handleTypeChange}
50
- data={translatedOptions}
51
- style={{ flex: 1 }}
52
92
  />
53
- <ColorInput
54
- value={String((value.attributes || {}).icon_color || colors[0])}
93
+ <SourceColorSelector
94
+ value={String(value.attributes?.icon_color)}
55
95
  onChange={handleColorChange}
56
- swatches={colors}
57
- style={{ flex: 1 }}
58
96
  />
59
97
  </Group>
60
98
  );
@@ -1,8 +1,9 @@
1
- import { IconUitSocialMediaLogo } from '@/assets/icons/generated/uit-social-media-logo';
2
- import { IconStreamlineCyberNewspaper2 } from '@/assets/icons/generated/streamline-cyber-newspaper-2';
3
- import { IconBasilDocumentSolid } from '@/assets/icons/generated/basil-document-solid';
4
- import { IconBoxiconsBook } from '@/assets/icons/generated/boxicons-book';
5
- import { IconGgWebsite } from '@/assets/icons/generated/gg-website';
1
+ import { IconBasilDocumentSolid } from '../../assets/icons/generated/basil-document-solid';
2
+ import { IconBoxiconsBook } from '../../assets/icons/generated/boxicons-book';
3
+ import { IconUitSocialMediaLogo } from '../../assets/icons/generated/uit-social-media-logo';
4
+ import { IconGgWebsite } from '../../assets/icons/generated/gg-website';
5
+ import { IconStreamlineCyberNewspaper2 } from '../../assets/icons/generated/streamline-cyber-newspaper-2';
6
+
6
7
 
7
8
  interface IconOption {
8
9
  value: string;
@@ -4,16 +4,45 @@ import { Group, Select, ColorInput } from "@mantine/core";
4
4
  import { ICON_OPTIONS } from "./icons";
5
5
  import { WebsiteIcon } from "./Icon";
6
6
 
7
- interface WebsiteIconSelectProps {
8
- value: Website;
9
- onChange: (value: Website) => void;
7
+ interface WebsiteIconSelectorProps {
8
+ data: Website;
9
+ value?: string | null;
10
+ onChange: (value: string | null) => void;
10
11
  }
11
12
 
12
- export const WebsiteIconSelect: React.FC<WebsiteIconSelectProps> = ({
13
+ export const WebsiteIconSelector: React.FC<WebsiteIconSelectorProps> = ({
14
+ data,
13
15
  value,
14
16
  onChange,
15
17
  }) => {
16
18
  const { t } = useTranslation();
19
+
20
+ const translatedOptions = ICON_OPTIONS.map((option) => ({
21
+ ...option,
22
+ label: t(`website.type.${option.label}`),
23
+ }));
24
+
25
+ return (
26
+ <Select
27
+ leftSection={<WebsiteIcon website={data} />}
28
+ defaultValue={translatedOptions[0].value}
29
+ value={value}
30
+ onChange={onChange}
31
+ data={translatedOptions}
32
+ style={{ flex: 1 }}
33
+ />
34
+ );
35
+ };
36
+
37
+ interface WebsiteColorSelectorProps {
38
+ value?: string | null;
39
+ onChange: (value: string | null) => void;
40
+ }
41
+
42
+ export const WebsiteColorSelector: React.FC<WebsiteColorSelectorProps> = ({
43
+ value,
44
+ onChange,
45
+ }) => {
17
46
  const colors = [
18
47
  "#0089ff",
19
48
  "#ff0000",
@@ -24,37 +53,46 @@ export const WebsiteIconSelect: React.FC<WebsiteIconSelectProps> = ({
24
53
  "#7950f2",
25
54
  ];
26
55
 
56
+ return (
57
+ <ColorInput
58
+ value={value || colors[0]}
59
+ onChange={onChange}
60
+ swatches={colors}
61
+ style={{ flex: 1 }}
62
+ />
63
+ );
64
+ };
65
+
66
+ interface WebsiteIconSelectProps {
67
+ value: Website;
68
+ onChange: (value: Website) => void;
69
+ }
70
+
71
+ export const WebsiteIconSelect: React.FC<WebsiteIconSelectProps> = ({
72
+ value,
73
+ onChange,
74
+ }) => {
27
75
  const handleTypeChange = (type: string | null) => {
28
76
  onChange({ ...value, title: type || undefined });
29
77
  };
30
78
 
31
- const handleColorChange = (color: string) => {
79
+ const handleColorChange = (color: string | null) => {
32
80
  onChange({
33
81
  ...value,
34
82
  attributes: { ...(value.attributes || {}), icon_color: color },
35
83
  });
36
84
  };
37
85
 
38
- const translatedOptions = ICON_OPTIONS.map((option) => ({
39
- ...option,
40
- label: t(`website.type.${option.label}`),
41
- }));
42
-
43
86
  return (
44
87
  <Group>
45
- <Select
46
- leftSection={<WebsiteIcon website={value} />}
47
- defaultValue={translatedOptions[0].value}
48
- value={value.type}
88
+ <WebsiteIconSelector
89
+ data={value}
90
+ value={value.title}
49
91
  onChange={handleTypeChange}
50
- data={translatedOptions}
51
- style={{ flex: 1 }}
52
92
  />
53
- <ColorInput
54
- value={String((value.attributes || {}).icon_color || colors[0])}
93
+ <WebsiteColorSelector
94
+ value={String(value.attributes?.icon_color)}
55
95
  onChange={handleColorChange}
56
- swatches={colors}
57
- style={{ flex: 1 }}
58
96
  />
59
97
  </Group>
60
98
  );
@@ -1,6 +1,7 @@
1
- import { IconMdiForum } from '@/assets/icons/generated/mdi-forum';
2
- import { IconStreamlineCyberNewspaper2 } from '@/assets/icons/generated/streamline-cyber-newspaper-2';
3
- import { IconMingcuteGovernmentLine } from '@/assets/icons/generated/mingcute-government-line';
1
+ import { IconMdiForum } from '../../assets/icons/generated/mdi-forum';
2
+ import { IconStreamlineCyberNewspaper2 } from '../../assets/icons/generated/streamline-cyber-newspaper-2';
3
+ import { IconMingcuteGovernmentLine } from '../../assets/icons/generated/mingcute-government-line';
4
+
4
5
 
5
6
  import { BuildingOfficeIcon } from '@heroicons/react/24/solid';
6
7