tycho-components 0.26.1 → 0.28.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/dist/common/AppForm/AppForm.d.ts +4 -4
- package/dist/common/AppForm/FormColorField.d.ts +4 -4
- package/dist/common/AppForm/FormColorField.js +3 -2
- package/dist/common/AppSwitchGroup/AppSwitchGroup.d.ts +4 -4
- package/dist/configs/index.d.ts +2 -1
- package/dist/configs/index.js +1 -1
- package/dist/configs/localization/ParametersTexts.js +6 -6
- package/dist/configs/types/Corpus.d.ts +2 -0
- package/dist/configs/types/EditionTiers.d.ts +36 -13
- package/dist/configs/types/EditionTiers.js +83 -14
- package/dist/configs/useMessageUtils.d.ts +1 -1
- package/dist/features/SentenceView/SentenceEditionTiers.d.ts +3 -1
- package/dist/features/SentenceView/SentenceEditionTiers.js +11 -14
- package/dist/features/SentenceView/SentenceView.js +3 -1
- package/dist/features/TreeView/cytoscape/CytoscapeTreeConverter.js +8 -1
- package/dist/features/TreeView/cytoscape/SyntreesCytoscape.d.ts +8 -2
- package/dist/features/TreeView/cytoscape/SyntreesCytoscape.js +9 -3
- package/dist/functions/EditionTierUtils.d.ts +16 -3
- package/dist/functions/EditionTierUtils.js +111 -19
- package/dist/functions/FilterUtils.d.ts +5 -5
- package/dist/functions/SentenceUtils.js +2 -6
- package/package.json +4 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { UseFormReturn } from 'react-hook-form';
|
|
1
|
+
import { FieldValues, UseFormReturn } from 'react-hook-form';
|
|
2
2
|
import { SelectItem } from 'tycho-storybook';
|
|
3
3
|
import { AppFormField } from './AppFormField';
|
|
4
4
|
import './style.scss';
|
|
5
|
-
type Props = {
|
|
5
|
+
type Props<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues> = {
|
|
6
6
|
fields: AppFormField[];
|
|
7
|
-
form: UseFormReturn<
|
|
7
|
+
form: UseFormReturn<TFieldValues, TContext, TTransformedValues>;
|
|
8
8
|
prefix?: string;
|
|
9
9
|
onChangeFunctions?: Record<string, (v: string | number | boolean) => void>;
|
|
10
10
|
onBlurFunctions?: Record<string, () => void>;
|
|
@@ -12,5 +12,5 @@ type Props = {
|
|
|
12
12
|
runtimeLoadOptions?: Record<string, (query: string) => Promise<SelectItem[]>>;
|
|
13
13
|
twoColumns?: boolean;
|
|
14
14
|
};
|
|
15
|
-
export default function AppForm({ fields, form, prefix, onChangeFunctions, onBlurFunctions, runtimeOptions, runtimeLoadOptions, twoColumns, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export default function AppForm<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues>({ fields, form, prefix, onChangeFunctions, onBlurFunctions, runtimeOptions, runtimeLoadOptions, twoColumns, }: Props<TFieldValues, TContext, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
|
|
16
16
|
export {};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { UseFormReturn } from 'react-hook-form';
|
|
1
|
+
import { FieldValues, UseFormReturn } from 'react-hook-form';
|
|
2
2
|
import '../AppColorpicker/style.scss';
|
|
3
|
-
type Props = {
|
|
3
|
+
type Props<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues> = {
|
|
4
4
|
attr: string;
|
|
5
5
|
label: string;
|
|
6
|
-
form: UseFormReturn<
|
|
6
|
+
form: UseFormReturn<TFieldValues, TContext, TTransformedValues>;
|
|
7
7
|
disabled?: boolean;
|
|
8
8
|
tooltipText?: string;
|
|
9
9
|
};
|
|
10
|
-
export default function FormColorField({ attr, label, form, disabled, tooltipText, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default function FormColorField<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues>({ attr, label, form, disabled, tooltipText, }: Props<TFieldValues, TContext, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
|
|
11
11
|
export {};
|
|
@@ -6,15 +6,16 @@ import { Button, Icon, Tooltip } from 'tycho-storybook';
|
|
|
6
6
|
import '../AppColorpicker/style.scss';
|
|
7
7
|
const defaultColor = '#FFFFFF';
|
|
8
8
|
export default function FormColorField({ attr, label, form, disabled, tooltipText, }) {
|
|
9
|
+
const fieldName = attr;
|
|
9
10
|
const { t } = useTranslation('common');
|
|
10
|
-
const formValue = form.watch(
|
|
11
|
+
const formValue = form.watch(fieldName);
|
|
11
12
|
const [openColor, setOpenColor] = useState(false);
|
|
12
13
|
const [color, setColor] = useState(defaultColor);
|
|
13
14
|
useEffect(() => {
|
|
14
15
|
setColor(formValue || defaultColor);
|
|
15
16
|
}, [formValue]);
|
|
16
17
|
const handleConfirm = () => {
|
|
17
|
-
form.setValue(
|
|
18
|
+
form.setValue(fieldName, color, { shouldDirty: true });
|
|
18
19
|
setOpenColor(false);
|
|
19
20
|
};
|
|
20
21
|
return (_jsxs("div", { className: "form-color-field", children: [_jsxs("div", { className: "form-color-field-label", children: [_jsx("span", { children: label }), tooltipText && (_jsx(Tooltip, { title: tooltipText, children: _jsx("span", { children: _jsx(Icon, { name: "help", className: "info", size: "x-small" }) }) }))] }), _jsxs("div", { className: "color-picker-container", children: [_jsx("div", { className: "swatch", style: { backgroundColor: color }, onClick: () => !disabled && setOpenColor(!openColor), onKeyDown: () => !disabled && setOpenColor(!openColor), role: "link", "aria-label": "open color picker", tabIndex: disabled ? -1 : 0 }), openColor && !disabled && (_jsxs(_Fragment, { children: [_jsx(HexColorPicker, { color: color, onChange: setColor }), _jsxs("div", { className: "buttons", children: [_jsx(Button, { text: t('button.confirm'), onClick: handleConfirm, size: "x-small" }), _jsx(Button, { text: t('button.cancel'), onClick: () => setOpenColor(false), color: "danger", size: "x-small" })] })] }))] })] }));
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { UseFormReturn } from 'react-hook-form';
|
|
1
|
+
import { FieldValues, UseFormReturn } from 'react-hook-form';
|
|
2
2
|
import { AppFormField } from '../AppForm/AppFormField';
|
|
3
3
|
import './style.scss';
|
|
4
|
-
type Props = {
|
|
4
|
+
type Props<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues> = {
|
|
5
5
|
fields: AppFormField[];
|
|
6
|
-
form: UseFormReturn<
|
|
6
|
+
form: UseFormReturn<TFieldValues, TContext, TTransformedValues>;
|
|
7
7
|
onToggle: (attr: string, value: boolean) => void;
|
|
8
8
|
hasRole?: (role: string) => boolean;
|
|
9
9
|
className?: string;
|
|
10
10
|
};
|
|
11
|
-
export default function AppSwitchGroup({ fields, form, onToggle, hasRole, className, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export default function AppSwitchGroup<TFieldValues extends FieldValues = FieldValues, TContext = any, TTransformedValues = TFieldValues>({ fields, form, onToggle, hasRole, className, }: Props<TFieldValues, TContext, TTransformedValues>): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
export {};
|
package/dist/configs/index.d.ts
CHANGED
|
@@ -12,7 +12,8 @@ export { DocumentStatusNames } from './types/Document';
|
|
|
12
12
|
export type { DocumentStatus, default as Document } from './types/Document';
|
|
13
13
|
export { CorpusImageTypeNames } from './types/CorpusImage';
|
|
14
14
|
export type { CorpusImage, CorpusImageType } from './types/CorpusImage';
|
|
15
|
-
export { EditionTiers } from './types/EditionTiers';
|
|
15
|
+
export { DEFAULT_EDITION_TIERS, EditionTiers, StructuralEditionTiers, isStructuralEditionTier, } from './types/EditionTiers';
|
|
16
|
+
export type { EditionGroup, EditionTierDefinition, EditionTierGroup, EditionTierSymbol, } from './types/EditionTiers';
|
|
16
17
|
export type { Parameter, ParameterType } from './types/Parameter';
|
|
17
18
|
export { SentenceStatusNames } from './types/SentenceStatus';
|
|
18
19
|
export type { SentenceStatus } from './types/SentenceStatus';
|
package/dist/configs/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export { default as ProfileService } from './services/ProfileService';
|
|
|
8
8
|
export { CorpusStatusNames } from './types/CorpusStatus';
|
|
9
9
|
export { DocumentStatusNames } from './types/Document';
|
|
10
10
|
export { CorpusImageTypeNames } from './types/CorpusImage';
|
|
11
|
-
export { EditionTiers } from './types/EditionTiers';
|
|
11
|
+
export { DEFAULT_EDITION_TIERS, EditionTiers, StructuralEditionTiers, isStructuralEditionTier, } from './types/EditionTiers';
|
|
12
12
|
export { SentenceStatusNames } from './types/SentenceStatus';
|
|
13
13
|
export { UserStatusNames } from './types/User';
|
|
14
14
|
export { useCorpusUtils } from './useCorpusUtils';
|
|
@@ -27,8 +27,8 @@ export const ParametersTexts = {
|
|
|
27
27
|
"parameter.tooltip.useParticipantChat": "With this feature enabled, it is possible to add extra standard attributes to participants of transcriptions, as defined by the CHAT format com CHILDES project.",
|
|
28
28
|
"parameter.field.useSplit": "Enable Morpheme Edition",
|
|
29
29
|
"parameter.tooltip.useSplit": "Enables the use of fields related to morphemes in the corpora.",
|
|
30
|
-
"parameter.field.useEditionTiers": "Enable
|
|
31
|
-
"parameter.tooltip.useEditionTiers": "Enables
|
|
30
|
+
"parameter.field.useEditionTiers": "Enable Edition Tiers",
|
|
31
|
+
"parameter.tooltip.useEditionTiers": "Enables edition operations in the editor, including junction, segmentation, and configurable corpus edition tiers.",
|
|
32
32
|
"parameter.field.allowPosTagInclusion": "Allow POS Tag inclusion",
|
|
33
33
|
"parameter.tooltip.allowPosTagInclusion": "With this feature enabled, it is possible to add new POS tags to the list while editing sentences in the editor. A parser must be associated to the corpus.",
|
|
34
34
|
"parameter.field.useGrid": "Display Documents in Grid",
|
|
@@ -67,8 +67,8 @@ export const ParametersTexts = {
|
|
|
67
67
|
"parameter.tooltip.useParticipantChat": "Com este recurso habilitado, é possível adicionar atributos padrão extras aos participantes de transcrições, conforme definido pelo formato CHAT com o projeto CHILDES.",
|
|
68
68
|
"parameter.field.useSplit": "Habilitar Edição de Morfema",
|
|
69
69
|
"parameter.tooltip.useSplit": "Habilita o uso de campos relacionados a morfemas nos corpora.",
|
|
70
|
-
"parameter.field.useEditionTiers": "Habilitar Níveis de Edição
|
|
71
|
-
"parameter.tooltip.useEditionTiers": "Habilita
|
|
70
|
+
"parameter.field.useEditionTiers": "Habilitar Níveis de Edição",
|
|
71
|
+
"parameter.tooltip.useEditionTiers": "Habilita operações de edição no editor, incluindo junção, segmentação e níveis de edição configuráveis do corpus.",
|
|
72
72
|
"parameter.field.allowPosTagInclusion": "Permitir Inclusão de Tag POS",
|
|
73
73
|
"parameter.tooltip.allowPosTagInclusion": "Com este recurso habilitado, é possível adicionar novas tags POS à lista durante a edição de frases no editor. Um parser deve estar associado ao corpus.",
|
|
74
74
|
"parameter.field.useGrid": "Exibir Documentos em Grade",
|
|
@@ -107,8 +107,8 @@ export const ParametersTexts = {
|
|
|
107
107
|
"parameter.tooltip.useParticipantChat": "Con questa funzione abilitata, è possibile aggiungere attributi standard extra ai partecipanti delle trascrizioni, come definito dal formato CHAT con il progetto CHILDES.",
|
|
108
108
|
"parameter.field.useSplit": "Abilita Modifica Morfemi",
|
|
109
109
|
"parameter.tooltip.useSplit": "Abilita l'uso di campi relativi ai morfemi nei corpora.",
|
|
110
|
-
"parameter.field.useEditionTiers": "Abilita Livelli di Edizione
|
|
111
|
-
"parameter.tooltip.useEditionTiers": "Abilita
|
|
110
|
+
"parameter.field.useEditionTiers": "Abilita Livelli di Edizione",
|
|
111
|
+
"parameter.tooltip.useEditionTiers": "Abilita le operazioni di edizione nell'editor, inclusi giunzione, segmentazione e livelli di edizione configurabili del corpus.",
|
|
112
112
|
"parameter.field.allowPosTagInclusion": "Permetti Inclusione Tag POS",
|
|
113
113
|
"parameter.tooltip.allowPosTagInclusion": "Con questa funzione abilitata, è possibile aggiungere nuovi tag POS all'elenco durante l'editing delle frasi in editor. Un parser deve essere associato al corpus.",
|
|
114
114
|
"parameter.field.useGrid": "Visualizza Documenti a Griglia",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CorpusImage } from './CorpusImage';
|
|
2
2
|
import { CorpusStatus } from './CorpusStatus';
|
|
3
|
+
import { EditionTierDefinition } from './EditionTiers';
|
|
3
4
|
import { User } from './User';
|
|
4
5
|
export type Corpus = {
|
|
5
6
|
id?: number;
|
|
@@ -8,6 +9,7 @@ export type Corpus = {
|
|
|
8
9
|
picture: string;
|
|
9
10
|
uploadDir: string;
|
|
10
11
|
parameters: Record<string, any>;
|
|
12
|
+
editionTiers?: EditionTierDefinition[];
|
|
11
13
|
status: CorpusStatus;
|
|
12
14
|
opened: boolean;
|
|
13
15
|
featured?: boolean;
|
|
@@ -1,13 +1,36 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
1
|
+
export type EditionTierGroup = 'semiDiplomatic' | 'modernized';
|
|
2
|
+
export type EditionTierDefinition = {
|
|
3
|
+
symbol: string;
|
|
4
|
+
label: string;
|
|
5
|
+
order: number;
|
|
6
|
+
group: EditionTierGroup;
|
|
7
|
+
abbreviation: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const StructuralEditionTiers: {
|
|
10
|
+
readonly ORIGINAL: "ori";
|
|
11
|
+
readonly JUNCTION: "jun";
|
|
12
|
+
readonly SEGMENTATION: "seg";
|
|
13
|
+
};
|
|
14
|
+
/** Default configurable tier symbols (structural ops are excluded). */
|
|
15
|
+
export declare const EditionTiers: {
|
|
16
|
+
readonly ORIGINAL: "ori";
|
|
17
|
+
readonly JUNCTION: "jun";
|
|
18
|
+
readonly SEGMENTATION: "seg";
|
|
19
|
+
readonly SPELLING: "gra";
|
|
20
|
+
readonly EXPANSION: "exp";
|
|
21
|
+
readonly CORRECTION: "cor";
|
|
22
|
+
readonly PUNCTUATION: "pon";
|
|
23
|
+
readonly ILLEGIBLE: "ileg";
|
|
24
|
+
readonly MODERNIZATION: "mod";
|
|
25
|
+
readonly PADRONIZATION: "pad";
|
|
26
|
+
readonly INFLECTION: "fle";
|
|
27
|
+
};
|
|
28
|
+
export type EditionTierSymbol = (typeof EditionTiers)[keyof typeof EditionTiers];
|
|
29
|
+
export declare const DEFAULT_EDITION_TIERS: EditionTierDefinition[];
|
|
30
|
+
export type EditionGroup = {
|
|
31
|
+
id: string;
|
|
32
|
+
labelKey: string;
|
|
33
|
+
tiers: string[];
|
|
34
|
+
defaultTier: string;
|
|
35
|
+
};
|
|
36
|
+
export declare const isStructuralEditionTier: (symbol: string) => boolean;
|
|
@@ -1,14 +1,83 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
export const StructuralEditionTiers = {
|
|
2
|
+
ORIGINAL: 'ori',
|
|
3
|
+
JUNCTION: 'jun',
|
|
4
|
+
SEGMENTATION: 'seg',
|
|
5
|
+
};
|
|
6
|
+
/** Default configurable tier symbols (structural ops are excluded). */
|
|
7
|
+
export const EditionTiers = {
|
|
8
|
+
ORIGINAL: 'ori',
|
|
9
|
+
JUNCTION: 'jun',
|
|
10
|
+
SEGMENTATION: 'seg',
|
|
11
|
+
SPELLING: 'gra',
|
|
12
|
+
EXPANSION: 'exp',
|
|
13
|
+
CORRECTION: 'cor',
|
|
14
|
+
PUNCTUATION: 'pon',
|
|
15
|
+
ILLEGIBLE: 'ileg',
|
|
16
|
+
MODERNIZATION: 'mod',
|
|
17
|
+
PADRONIZATION: 'pad',
|
|
18
|
+
INFLECTION: 'fle',
|
|
19
|
+
};
|
|
20
|
+
export const DEFAULT_EDITION_TIERS = [
|
|
21
|
+
{
|
|
22
|
+
symbol: EditionTiers.SPELLING,
|
|
23
|
+
label: 'Spelling',
|
|
24
|
+
order: 1,
|
|
25
|
+
group: 'semiDiplomatic',
|
|
26
|
+
abbreviation: false,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
symbol: EditionTiers.EXPANSION,
|
|
30
|
+
label: 'Expansion',
|
|
31
|
+
order: 2,
|
|
32
|
+
group: 'semiDiplomatic',
|
|
33
|
+
abbreviation: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
symbol: EditionTiers.CORRECTION,
|
|
37
|
+
label: 'Correction',
|
|
38
|
+
order: 3,
|
|
39
|
+
group: 'semiDiplomatic',
|
|
40
|
+
abbreviation: false,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
symbol: EditionTiers.PUNCTUATION,
|
|
44
|
+
label: 'Punctuation',
|
|
45
|
+
order: 4,
|
|
46
|
+
group: 'semiDiplomatic',
|
|
47
|
+
abbreviation: false,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
symbol: EditionTiers.ILLEGIBLE,
|
|
51
|
+
label: 'Illegible',
|
|
52
|
+
order: 5,
|
|
53
|
+
group: 'semiDiplomatic',
|
|
54
|
+
abbreviation: false,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
symbol: EditionTiers.MODERNIZATION,
|
|
58
|
+
label: 'Modernization',
|
|
59
|
+
order: 6,
|
|
60
|
+
group: 'modernized',
|
|
61
|
+
abbreviation: false,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
symbol: EditionTiers.PADRONIZATION,
|
|
65
|
+
label: 'Padronization',
|
|
66
|
+
order: 7,
|
|
67
|
+
group: 'modernized',
|
|
68
|
+
abbreviation: false,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
symbol: EditionTiers.INFLECTION,
|
|
72
|
+
label: 'Inflection',
|
|
73
|
+
order: 8,
|
|
74
|
+
group: 'modernized',
|
|
75
|
+
abbreviation: false,
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
const RESERVED_SYMBOLS = new Set([
|
|
79
|
+
StructuralEditionTiers.ORIGINAL,
|
|
80
|
+
StructuralEditionTiers.JUNCTION,
|
|
81
|
+
StructuralEditionTiers.SEGMENTATION,
|
|
82
|
+
]);
|
|
83
|
+
export const isStructuralEditionTier = (symbol) => RESERVED_SYMBOLS.has(symbol);
|
|
@@ -13,7 +13,7 @@ export declare const useMessageUtils: () => {
|
|
|
13
13
|
dispatchLoading: (val: boolean, text?: string) => void;
|
|
14
14
|
dispatchError: ({ err, t, key }: ErrorDispatcher) => void;
|
|
15
15
|
dispatchMessage: ({ key, ns, t }: MessageDispatcher) => void;
|
|
16
|
-
dispatchMessageDirect: (value: string, type?: "success" | "error") => void;
|
|
16
|
+
dispatchMessageDirect: (value: string, type?: "success" | "error" | "warning") => void;
|
|
17
17
|
isLoading: () => boolean;
|
|
18
18
|
dispatchSilent: (val: boolean) => void;
|
|
19
19
|
isSilentLoading: () => boolean;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { Corpus } from '../../configs/types/Corpus';
|
|
1
2
|
import { Token } from '../../configs/types/Struct';
|
|
2
3
|
import './style.scss';
|
|
3
4
|
type Props = {
|
|
4
5
|
tokens: Token[];
|
|
5
6
|
displayOriginal?: boolean;
|
|
7
|
+
corpus?: Corpus | null;
|
|
6
8
|
};
|
|
7
|
-
export default function SentenceEditionTiers({ tokens, displayOriginal, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export default function SentenceEditionTiers({ tokens, displayOriginal, corpus, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
10
|
export {};
|
|
@@ -3,25 +3,22 @@ import { useTranslation } from 'react-i18next';
|
|
|
3
3
|
import EditionTierUtils from '../../functions/EditionTierUtils';
|
|
4
4
|
import SentenceUtils from '../../functions/SentenceUtils';
|
|
5
5
|
import './style.scss';
|
|
6
|
-
export default function SentenceEditionTiers({ tokens, displayOriginal, }) {
|
|
6
|
+
export default function SentenceEditionTiers({ tokens, displayOriginal, corpus, }) {
|
|
7
7
|
const { t } = useTranslation('sentence');
|
|
8
8
|
const { skipToken } = SentenceUtils;
|
|
9
|
-
const { getIterateTiers,
|
|
9
|
+
const { getIterateTiers, getTierLabel, getEditionForToken, getOriginalValue, } = EditionTierUtils;
|
|
10
10
|
return (_jsxs(_Fragment, { children: [displayOriginal && (_jsxs("tr", { className: "word-tier", children: [_jsx("td", { children: t('label.tier.original') }), tokens.map((thisToken, idy) => {
|
|
11
11
|
if (skipToken(thisToken)) {
|
|
12
12
|
return true;
|
|
13
13
|
}
|
|
14
14
|
const value = getOriginalValue(thisToken);
|
|
15
|
-
return (_jsx("td", { className: "text-center", colSpan: thisToken.splits ? thisToken.splits.length : 1, children: _jsx("span", { className: value ? '' : 'empty', children: value || t('label.empty') }) }));
|
|
16
|
-
})] })), getIterateTiers().map((tier, idx) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return (_jsx("td", { className: "text-center", colSpan: thisToken.splits ? thisToken.splits.length : 1, children: _jsx("span", { className: value ? '' : 'empty', children: value || t('label.empty') }) }, `${thisToken.p}_${idx.valueOf()}_${idy.valueOf()}`));
|
|
25
|
-
})] }, idx.valueOf()));
|
|
26
|
-
})] }));
|
|
15
|
+
return (_jsx("td", { className: "text-center", colSpan: thisToken.splits ? thisToken.splits.length : 1, children: _jsx("span", { className: value ? '' : 'empty', children: value || t('label.empty') }) }, `original_${thisToken.p}_${idy}`));
|
|
16
|
+
})] })), getIterateTiers(corpus).map((tier, idx) => (_jsxs("tr", { className: "word-tier", children: [_jsx("td", { children: getTierLabel(tier, corpus, t) }), tokens.map((thisToken, idy) => {
|
|
17
|
+
if (skipToken(thisToken)) {
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
const tierEdition = getEditionForToken(thisToken);
|
|
21
|
+
const value = (tierEdition?.ops || {})[tier] || '';
|
|
22
|
+
return (_jsx("td", { className: "text-center", colSpan: thisToken.splits ? thisToken.splits.length : 1, children: _jsx("span", { className: value ? '' : 'empty', children: value || t('label.empty') }) }, `${thisToken.p}_${idx}_${idy}`));
|
|
23
|
+
})] }, tier)))] }));
|
|
27
24
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCorpusUtils } from '../../configs/useCorpusUtils';
|
|
2
3
|
import SentenceUtils from '../../functions/SentenceUtils';
|
|
3
4
|
import SentenceEditionTiers from './SentenceEditionTiers';
|
|
4
5
|
import SentenceMorphemeTiers from './SentenceMorphemeTiers';
|
|
@@ -8,5 +9,6 @@ import SentenceWordTiers from './SentenceWordTiers';
|
|
|
8
9
|
import './style.scss';
|
|
9
10
|
export default function SentenceView({ wordTiers, morphemeTiers, struct, useMorphemes, useEditionTiers, displayOriginal, }) {
|
|
10
11
|
const tokens = SentenceUtils.sort(struct);
|
|
11
|
-
|
|
12
|
+
const { getCorpus } = useCorpusUtils();
|
|
13
|
+
return (_jsx("div", { className: "sentence-view-container", children: _jsx("div", { className: "body", children: _jsx("table", { className: "table table-striped", children: _jsxs("tbody", { children: [_jsx(SentenceValues, { tokens: tokens }), _jsx(SentenceTags, { tokens: tokens }), useEditionTiers && (_jsx(SentenceEditionTiers, { tokens: tokens, displayOriginal: displayOriginal, corpus: getCorpus() })), wordTiers && (_jsx(SentenceWordTiers, { tokens: tokens, wordTiers: wordTiers })), useMorphemes && morphemeTiers && (_jsx(SentenceMorphemeTiers, { struct: struct, morphemeTiers: morphemeTiers }))] }) }) }) }));
|
|
12
14
|
}
|
|
@@ -228,7 +228,14 @@ export default class CytoscapeTreeConverter {
|
|
|
228
228
|
return `${token.p}`;
|
|
229
229
|
}
|
|
230
230
|
findParent(struct, chunk) {
|
|
231
|
-
|
|
231
|
+
if (chunk.l <= 0)
|
|
232
|
+
return null;
|
|
233
|
+
for (let level = chunk.l - 1; level >= 0; level--) {
|
|
234
|
+
const parent = this.tightestChunk(this.findContainingChunks(struct, level, chunk.i, chunk.f));
|
|
235
|
+
if (parent)
|
|
236
|
+
return parent;
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
232
239
|
}
|
|
233
240
|
findContainingChunks(struct, level, i, f) {
|
|
234
241
|
return struct.chunks.filter((c) => c.l === level && i >= c.i && f <= c.f);
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import cytoscape, { Core } from 'cytoscape';
|
|
1
|
+
import cytoscape, { Core, Position } from 'cytoscape';
|
|
2
2
|
import { CytoscapeTree } from '../../../configs/types/Tree';
|
|
3
|
+
export type CytoscapeViewport = {
|
|
4
|
+
zoom: number;
|
|
5
|
+
pan: Position;
|
|
6
|
+
};
|
|
3
7
|
type Props = {
|
|
4
8
|
selector: string;
|
|
5
9
|
tree: CytoscapeTree;
|
|
@@ -8,8 +12,10 @@ type Props = {
|
|
|
8
12
|
wheelSensitivity?: number;
|
|
9
13
|
onReady?: (cy: Core) => void;
|
|
10
14
|
autoungrabify?: boolean;
|
|
15
|
+
fit?: boolean;
|
|
16
|
+
viewport?: CytoscapeViewport;
|
|
11
17
|
};
|
|
12
18
|
declare const SyntreesCytoscape: {
|
|
13
|
-
init: ({ selector, tree, dagre, stylesheet, wheelSensitivity, onReady, autoungrabify, }: Props) => Core;
|
|
19
|
+
init: ({ selector, tree, dagre, stylesheet, wheelSensitivity, onReady, autoungrabify, fit, viewport, }: Props) => Core;
|
|
14
20
|
};
|
|
15
21
|
export default SyntreesCytoscape;
|
|
@@ -3,7 +3,7 @@ import defaultStylesheet from './CytoscapeStylesheet';
|
|
|
3
3
|
// @ts-ignore
|
|
4
4
|
import nodeHtmlLabel from 'cytoscape-node-html-label';
|
|
5
5
|
nodeHtmlLabel(cytoscape);
|
|
6
|
-
const init = ({ selector, tree, dagre = false, stylesheet = defaultStylesheet, wheelSensitivity = 1.5, onReady, autoungrabify = true, }) => {
|
|
6
|
+
const init = ({ selector, tree, dagre = false, stylesheet = defaultStylesheet, wheelSensitivity = 1.5, onReady, autoungrabify = true, fit = true, viewport, }) => {
|
|
7
7
|
destroy(selector);
|
|
8
8
|
const cy = cytoscape({
|
|
9
9
|
container: document.getElementById(selector),
|
|
@@ -57,8 +57,14 @@ const init = ({ selector, tree, dagre = false, stylesheet = defaultStylesheet, w
|
|
|
57
57
|
]);
|
|
58
58
|
cy._htmlLabelsApplied = true;
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
if (fit) {
|
|
61
|
+
cy.fit();
|
|
62
|
+
cy.center();
|
|
63
|
+
}
|
|
64
|
+
else if (viewport) {
|
|
65
|
+
cy.zoom(viewport.zoom);
|
|
66
|
+
cy.pan(viewport.pan);
|
|
67
|
+
}
|
|
62
68
|
dagre && cy.layout({ name: 'dagre' }).run();
|
|
63
69
|
onReady && onReady(cy);
|
|
64
70
|
});
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EditionGroup, EditionTierDefinition } from '../configs/types/EditionTiers';
|
|
2
|
+
import { Corpus } from '../configs/types/Corpus';
|
|
2
3
|
import { Token } from '../configs/types/Struct';
|
|
3
4
|
declare const EditionTierUtils: {
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
getCorpusEditionTiers: (corpus?: Corpus | null) => EditionTierDefinition[];
|
|
6
|
+
normalizeOrder: (tiers: EditionTierDefinition[]) => EditionTierDefinition[];
|
|
7
|
+
getIterateTiers: (corpus?: Corpus | null) => string[];
|
|
8
|
+
getAbbreviationTiers: (corpus?: Corpus | null) => string[];
|
|
9
|
+
getParserTier: (corpus?: Corpus | null) => EditionTierDefinition | undefined;
|
|
10
|
+
getEditionTierName: (symbol: string) => string;
|
|
11
|
+
getTierLabel: (symbol: string, corpus?: Corpus | null, t?: (key: string) => string) => string;
|
|
12
|
+
isUnderSelected: (selected: string, tier: string, corpus?: Corpus | null) => boolean;
|
|
13
|
+
buildEditionGroups: (corpus?: Corpus | null) => EditionGroup[];
|
|
14
|
+
findGroupForTier: (tier: string, corpus?: Corpus | null) => EditionGroup | undefined;
|
|
15
|
+
isAbbreviationTier: (symbol: string, corpus?: Corpus | null) => boolean;
|
|
16
|
+
validateEditionTiers: (tiers: EditionTierDefinition[]) => string | null;
|
|
17
|
+
isDefaultTierSymbol: (symbol: string) => boolean;
|
|
6
18
|
getEditionForToken: (token: Token) => any;
|
|
7
19
|
getOriginalValue: (token: Token) => string;
|
|
20
|
+
getDisplayTierOrder: (corpus?: Corpus | null) => string[];
|
|
8
21
|
};
|
|
9
22
|
export default EditionTierUtils;
|
|
@@ -1,4 +1,95 @@
|
|
|
1
|
-
import { EditionTiers } from '../configs/types/EditionTiers';
|
|
1
|
+
import { DEFAULT_EDITION_TIERS, EditionTiers, StructuralEditionTiers, isStructuralEditionTier, } from '../configs/types/EditionTiers';
|
|
2
|
+
const DEFAULT_SYMBOLS = new Set(DEFAULT_EDITION_TIERS.map((tier) => tier.symbol));
|
|
3
|
+
const getCorpusEditionTiers = (corpus) => {
|
|
4
|
+
if (!corpus?.editionTiers?.length) {
|
|
5
|
+
return DEFAULT_EDITION_TIERS.map((tier) => ({ ...tier }));
|
|
6
|
+
}
|
|
7
|
+
return [...corpus.editionTiers].sort((a, b) => a.order - b.order);
|
|
8
|
+
};
|
|
9
|
+
const normalizeOrder = (tiers) => tiers.map((tier, index) => ({ ...tier, order: index + 1 }));
|
|
10
|
+
const getIterateTiers = (corpus) => getCorpusEditionTiers(corpus).map((tier) => tier.symbol);
|
|
11
|
+
const getAbbreviationTiers = (corpus) => getCorpusEditionTiers(corpus)
|
|
12
|
+
.filter((tier) => tier.abbreviation)
|
|
13
|
+
.map((tier) => tier.symbol);
|
|
14
|
+
const getParserTier = (corpus) => {
|
|
15
|
+
const tiers = getCorpusEditionTiers(corpus);
|
|
16
|
+
return tiers[tiers.length - 1];
|
|
17
|
+
};
|
|
18
|
+
const getEditionTierName = (symbol) => {
|
|
19
|
+
const entry = Object.entries(EditionTiers).find(([, value]) => value === symbol);
|
|
20
|
+
return entry?.[0] || symbol;
|
|
21
|
+
};
|
|
22
|
+
const getTierLabel = (symbol, corpus, t) => {
|
|
23
|
+
const definition = getCorpusEditionTiers(corpus).find((tier) => tier.symbol === symbol);
|
|
24
|
+
if (definition?.label) {
|
|
25
|
+
return definition.label;
|
|
26
|
+
}
|
|
27
|
+
const key = getEditionTierName(symbol).toLowerCase();
|
|
28
|
+
if (t) {
|
|
29
|
+
return t(`sentence:label.tier.${key}`);
|
|
30
|
+
}
|
|
31
|
+
return key;
|
|
32
|
+
};
|
|
33
|
+
const isUnderSelected = (selected, tier, corpus) => {
|
|
34
|
+
const tiers = getIterateTiers(corpus);
|
|
35
|
+
const selectedIndex = tiers.indexOf(selected);
|
|
36
|
+
const tierIndex = tiers.indexOf(tier);
|
|
37
|
+
if (selectedIndex === -1 || tierIndex === -1) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return tierIndex <= selectedIndex;
|
|
41
|
+
};
|
|
42
|
+
const buildEditionGroups = (corpus) => {
|
|
43
|
+
const tiers = getCorpusEditionTiers(corpus);
|
|
44
|
+
const semi = tiers
|
|
45
|
+
.filter((tier) => tier.group === 'semiDiplomatic')
|
|
46
|
+
.map((tier) => tier.symbol);
|
|
47
|
+
const modern = tiers
|
|
48
|
+
.filter((tier) => tier.group === 'modernized')
|
|
49
|
+
.map((tier) => tier.symbol);
|
|
50
|
+
return [
|
|
51
|
+
{
|
|
52
|
+
id: 'diplomatic',
|
|
53
|
+
labelKey: 'edition.group.diplomatic',
|
|
54
|
+
tiers: [StructuralEditionTiers.ORIGINAL],
|
|
55
|
+
defaultTier: StructuralEditionTiers.ORIGINAL,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'semiDiplomatic',
|
|
59
|
+
labelKey: 'edition.group.semiDiplomatic',
|
|
60
|
+
tiers: semi,
|
|
61
|
+
defaultTier: semi[semi.length - 1] || EditionTiers.ILLEGIBLE,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'modernized',
|
|
65
|
+
labelKey: 'edition.group.modernized',
|
|
66
|
+
tiers: modern,
|
|
67
|
+
defaultTier: modern[modern.length - 1] || EditionTiers.INFLECTION,
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
};
|
|
71
|
+
const findGroupForTier = (tier, corpus) => buildEditionGroups(corpus).find((group) => group.tiers.includes(tier));
|
|
72
|
+
const isAbbreviationTier = (symbol, corpus) => getCorpusEditionTiers(corpus).some((tier) => tier.symbol === symbol && tier.abbreviation);
|
|
73
|
+
const validateEditionTiers = (tiers) => {
|
|
74
|
+
const symbols = new Set();
|
|
75
|
+
for (const tier of tiers) {
|
|
76
|
+
if (!tier.symbol?.trim()) {
|
|
77
|
+
return 'edition.tiers.symbol.required';
|
|
78
|
+
}
|
|
79
|
+
if (isStructuralEditionTier(tier.symbol)) {
|
|
80
|
+
return 'edition.tiers.symbol.reserved';
|
|
81
|
+
}
|
|
82
|
+
if (symbols.has(tier.symbol)) {
|
|
83
|
+
return 'edition.tiers.duplicate.symbol';
|
|
84
|
+
}
|
|
85
|
+
symbols.add(tier.symbol);
|
|
86
|
+
if (tier.group !== 'semiDiplomatic' && tier.group !== 'modernized') {
|
|
87
|
+
return 'edition.tiers.group.invalid';
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
};
|
|
92
|
+
const isDefaultTierSymbol = (symbol) => DEFAULT_SYMBOLS.has(symbol);
|
|
2
93
|
const getEditionForToken = (token) => {
|
|
3
94
|
if (token.eid)
|
|
4
95
|
return token.edition;
|
|
@@ -9,28 +100,29 @@ const getEditionForToken = (token) => {
|
|
|
9
100
|
}));
|
|
10
101
|
return { ...edition, o: token.v };
|
|
11
102
|
};
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
return ordered;
|
|
21
|
-
};
|
|
22
|
-
const getEditionTierName = (k) => {
|
|
23
|
-
const idx = Object.values(EditionTiers).indexOf(k);
|
|
24
|
-
const key = Object.keys(EditionTiers)[idx];
|
|
25
|
-
return key || k;
|
|
26
|
-
};
|
|
27
|
-
const getOriginalValue = (token) => {
|
|
28
|
-
return token.edition?.o || '';
|
|
29
|
-
};
|
|
103
|
+
const getOriginalValue = (token) => token.edition?.o || '';
|
|
104
|
+
const getDisplayTierOrder = (corpus) => [
|
|
105
|
+
StructuralEditionTiers.ORIGINAL,
|
|
106
|
+
StructuralEditionTiers.JUNCTION,
|
|
107
|
+
StructuralEditionTiers.SEGMENTATION,
|
|
108
|
+
...getIterateTiers(corpus),
|
|
109
|
+
];
|
|
30
110
|
const EditionTierUtils = {
|
|
111
|
+
getCorpusEditionTiers,
|
|
112
|
+
normalizeOrder,
|
|
31
113
|
getIterateTiers,
|
|
114
|
+
getAbbreviationTiers,
|
|
115
|
+
getParserTier,
|
|
32
116
|
getEditionTierName,
|
|
117
|
+
getTierLabel,
|
|
118
|
+
isUnderSelected,
|
|
119
|
+
buildEditionGroups,
|
|
120
|
+
findGroupForTier,
|
|
121
|
+
isAbbreviationTier,
|
|
122
|
+
validateEditionTiers,
|
|
123
|
+
isDefaultTierSymbol,
|
|
33
124
|
getEditionForToken,
|
|
34
125
|
getOriginalValue,
|
|
126
|
+
getDisplayTierOrder,
|
|
35
127
|
};
|
|
36
128
|
export default EditionTierUtils;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { UseFormReturn } from 'react-hook-form';
|
|
1
|
+
import { FieldValues, UseFormReturn } from 'react-hook-form';
|
|
2
2
|
export type DefaultOption = {
|
|
3
3
|
label: string;
|
|
4
4
|
value: any;
|
|
5
5
|
};
|
|
6
6
|
declare const FilterUtils: {
|
|
7
|
-
apply: (form: UseFormReturn<
|
|
8
|
-
clear: (form: UseFormReturn<
|
|
7
|
+
apply: <T extends FieldValues, TContext = any, TTransformedValues = T>(form: UseFormReturn<T, TContext, TTransformedValues>, setFilter: (f: any) => void, onClose: () => void, emptyPageable: any) => void;
|
|
8
|
+
clear: <T extends FieldValues, TContext = any, TTransformedValues = T>(form: UseFormReturn<T, TContext, TTransformedValues>, setFilter: (f: any) => void, onClose: () => void, clearValues: any) => void;
|
|
9
9
|
isSelected: (filter: any) => boolean;
|
|
10
|
-
reset: (form: UseFormReturn<
|
|
11
|
-
enter: (form: UseFormReturn<
|
|
10
|
+
reset: <T extends FieldValues, TContext = any, TTransformedValues = T>(form: UseFormReturn<T, TContext, TTransformedValues>, setFilter: (p: any) => void, clearValues: any) => void;
|
|
11
|
+
enter: <T extends FieldValues, TContext = any, TTransformedValues = T>(form: UseFormReturn<T, TContext, TTransformedValues>, setFilter: (f: any) => void, event: React.KeyboardEvent<HTMLDivElement>, onClose: () => void, emptyPageable: any) => void;
|
|
12
12
|
};
|
|
13
13
|
export default FilterUtils;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import EditionTierUtils from './EditionTierUtils';
|
|
2
2
|
const getTag = (token) => {
|
|
3
3
|
if (token.split)
|
|
4
4
|
return token.split.t || '';
|
|
@@ -65,11 +65,7 @@ const isFirstFromSplit = (token) => {
|
|
|
65
65
|
return false;
|
|
66
66
|
return token.split.idx !== undefined && token.split.idx === 0;
|
|
67
67
|
};
|
|
68
|
-
const getEditionTierName = (k) =>
|
|
69
|
-
const idx = Object.values(EditionTiers).indexOf(k);
|
|
70
|
-
const key = Object.keys(EditionTiers)[idx];
|
|
71
|
-
return key || k;
|
|
72
|
-
};
|
|
68
|
+
const getEditionTierName = (k) => EditionTierUtils.getEditionTierName(k);
|
|
73
69
|
const SentenceUtils = {
|
|
74
70
|
sort,
|
|
75
71
|
getAsText,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tycho-components",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.28.0",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"react-i18next": "^13.0.2",
|
|
83
83
|
"react-router-dom": "^6.14.2",
|
|
84
84
|
"react-toastify": "^9.1.3",
|
|
85
|
-
"tycho-storybook": "0.
|
|
85
|
+
"tycho-storybook": "0.10.0",
|
|
86
86
|
"wavesurfer-react": "^2.2.2",
|
|
87
87
|
"wavesurfer.js": "^6.6.3"
|
|
88
88
|
},
|
|
@@ -107,9 +107,11 @@
|
|
|
107
107
|
"eslint-plugin-storybook": "^0.11.2",
|
|
108
108
|
"react": "^18.2.0",
|
|
109
109
|
"react-dom": "^18.2.0",
|
|
110
|
+
"react-hook-form": "7.78.0",
|
|
110
111
|
"react-toastify": "^9.1.3",
|
|
111
112
|
"sass-embedded": "^1.97.2",
|
|
112
113
|
"storybook": "^10.1.11",
|
|
114
|
+
"tycho-storybook": "^0.10.0",
|
|
113
115
|
"typescript": "^5.7.3",
|
|
114
116
|
"vite": "^7.0.0",
|
|
115
117
|
"vitest": "^3.2.6",
|