Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
324 commits
Select commit Hold shift + click to select a range
eb7cdd8
Update comments icon
riccio82 Feb 24, 2026
b8ce809
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Feb 25, 2026
d73d918
Update plural rules
riccio82 Feb 25, 2026
a9d180a
Refactoring: chenge replace hardcoded colors with variables
riccio82 Feb 26, 2026
99e4bfe
Tab translation memory and Machine translation
piedicianni Feb 26, 2026
ee2a0aa
Update js tests
riccio82 Feb 26, 2026
8b1cbf3
Css: refactor colors variables
riccio82 Feb 27, 2026
44e289c
CSS: restore old variables name
riccio82 Feb 27, 2026
76f79a9
Settings panel
piedicianni Mar 2, 2026
8076165
Removed component MenuButton
piedicianni Mar 2, 2026
7ec8715
Update button css
riccio82 Mar 2, 2026
d29be24
Some fix
piedicianni Mar 3, 2026
95acec1
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Mar 3, 2026
c561aed
Update submodule
riccio82 Mar 3, 2026
13322e8
Update submodules
riccio82 Mar 3, 2026
8cfd1a5
Settings panel done
piedicianni Mar 3, 2026
fed2ff3
Some improvements
piedicianni Mar 3, 2026
452c1ae
Improvements
piedicianni Mar 4, 2026
ed879a8
New layout
riccio82 Mar 4, 2026
cc58aea
AnalizeHeader refactoring
riccio82 Mar 4, 2026
2acc606
Analyze page: project header
riccio82 Mar 5, 2026
ea92e2f
Analysis page: update design - wip
riccio82 Mar 5, 2026
216f1ac
AI Assistant refactoring
mauretto78 Jan 22, 2026
f944a2f
Added ai-assistant routes
mauretto78 Jan 23, 2026
afec518
Fix code
mauretto78 Jan 26, 2026
434e4f6
missing 'id_client'
mauretto78 Jan 27, 2026
6e50a1b
FE integration wip
piedicianni Feb 10, 2026
ec80b4d
Wip
piedicianni Feb 11, 2026
f47fc75
Wip
piedicianni Feb 12, 2026
ac34df1
Workers
mauretto78 Feb 12, 2026
6736c04
Fix css box alignment
piedicianni Feb 12, 2026
686b8cd
Feedback integration
piedicianni Feb 13, 2026
0f41afe
Ai alternatives request
piedicianni Feb 16, 2026
0a49724
Fix
piedicianni Feb 16, 2026
2b616c6
Fix
piedicianni Feb 16, 2026
d45fb94
controller
mauretto78 Feb 16, 2026
51edea1
Worker improvement
mauretto78 Feb 16, 2026
7061ad0
Fix worker
mauretto78 Feb 16, 2026
134dfff
altTrans improvement
mauretto78 Feb 16, 2026
614714f
wrong error message
mauretto78 Feb 17, 2026
cf54d70
Alternatives request added job lara styleΓΉ
piedicianni Feb 17, 2026
3ea8e73
prompt
mauretto78 Feb 17, 2026
d591480
Parameter renamed
mauretto78 Feb 17, 2026
8ce16f2
Enrich alternative translations
mauretto78 Feb 17, 2026
845a99d
Fixed manageAlternativeTranslations
mauretto78 Feb 18, 2026
320b245
fixed enrichAlternatives
mauretto78 Feb 18, 2026
9b1fb7d
Removed enrichResponse from Back-edn
mauretto78 Feb 19, 2026
33f2850
Fix
piedicianni Feb 18, 2026
df698ab
Fix
piedicianni Feb 18, 2026
7da661d
Fix
piedicianni Feb 18, 2026
ee49db4
Enrich ai alternatives
piedicianni Feb 19, 2026
9b2ac3d
Fix
piedicianni Feb 19, 2026
e6cb52f
Improved prompt
mauretto78 Feb 19, 2026
72fb6d5
Invoke tag projection
mauretto78 Feb 19, 2026
5765dc5
fix
mauretto78 Feb 19, 2026
5d1df79
Prompt improvements
mauretto78 Feb 20, 2026
e8fc436
Avoid split tags
piedicianni Feb 19, 2026
456f39a
prompt improvements
mauretto78 Feb 20, 2026
dd8d2ee
improved prompt
mauretto78 Feb 20, 2026
9e9ec13
feedback improvement
mauretto78 Feb 20, 2026
37fbf6e
refactorign
mauretto78 Feb 20, 2026
81de77f
prompt
mauretto78 Feb 20, 2026
000397b
Updated submodule
Ostico Feb 23, 2026
949418f
Fix
piedicianni Feb 20, 2026
70a91d7
Ai feedback request
piedicianni Feb 23, 2026
808de77
More improvements
piedicianni Feb 24, 2026
c9efc01
Editor page improvements
piedicianni Mar 9, 2026
c212c98
Fix
piedicianni Mar 9, 2026
71e927a
Editor buttons resolution rules
piedicianni Mar 9, 2026
c3dce0f
v3.5.27
riccio82 Feb 20, 2026
3820238
Update plural rules
riccio82 Mar 3, 2026
e68e42c
Update ICU tab
riccio82 Mar 3, 2026
89f402b
Update test
riccio82 Mar 3, 2026
9d9fadf
Refactor updload components and add tests
riccio82 Mar 3, 2026
a4cf2db
Refactor updload components and add tests
riccio82 Mar 3, 2026
9806e8d
Fixed languages (#4406)
mauretto78 Mar 4, 2026
a0b7bd4
Analyze page changed color help icon (#4407)
piedicianni Mar 4, 2026
eaec914
Updated dependency
Ostico Mar 4, 2026
1ce6a96
Improved icu management on filters call
Ostico Mar 5, 2026
f6495d4
Update dependency immutable to v5.1.5 [SECURITY] (#4410)
renovate[bot] Mar 5, 2026
ba923be
Update dependency eslint-plugin-jest to v29.14.0 (#4401)
renovate[bot] Mar 5, 2026
8294cfa
Update dependency msw to v2.12.10 (#4402)
renovate[bot] Mar 5, 2026
d5f8ff3
v3.5.28
mauretto78 Mar 5, 2026
75d3469
Fixed submodule
Ostico Mar 5, 2026
fe96e59
v3.5.29
Ostico Mar 5, 2026
0ff6726
Fixed unmarshalling as string
Ostico Mar 5, 2026
6ee8edf
v3.5.30
Ostico Mar 5, 2026
debcb82
Updated submodule
Ostico Mar 5, 2026
dd80cd1
v3.5.31
Ostico Mar 5, 2026
a1b02b1
Updated dependencies
Ostico Mar 5, 2026
46100b9
Updated submodule
Ostico Mar 6, 2026
0abc1ab
v3.5.32
Ostico Mar 6, 2026
8bec629
v3.5.33
Ostico Mar 6, 2026
659ae21
fix: deduplicate language codes by locale before checking allowed pairs
Ostico Mar 6, 2026
04f1707
v3.5.34
Ostico Mar 6, 2026
3df8a66
Updated submodule
Ostico Mar 6, 2026
d662e55
v3.5.35
Ostico Mar 6, 2026
9d69dc6
Update dependency @sentry/webpack-plugin to v4.9.1 (#4413)
renovate[bot] Mar 9, 2026
6429b32
Update dependency sass-loader to v16.0.7 (#4414)
renovate[bot] Mar 9, 2026
d4655c0
Update yarn.lock
riccio82 Mar 9, 2026
4de50e3
Analysis page: wip
riccio82 Mar 9, 2026
6701297
Analysis page: wip
riccio82 Mar 11, 2026
8d41ae7
Analysis page: wip
riccio82 Mar 11, 2026
493ab6f
Page my projects 2.0 - wip
piedicianni Mar 11, 2026
774d4e5
Analysis page: wip
riccio82 Mar 11, 2026
db43af1
Analysis page: wip
riccio82 Mar 11, 2026
a853eab
Outsource refactoring: wip
riccio82 Mar 12, 2026
0e28b3d
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Mar 12, 2026
95d9e77
Project page manage teams and members
piedicianni Mar 12, 2026
1e71608
fix merge
riccio82 Mar 12, 2026
c25622d
Fix css colors variables
piedicianni Mar 12, 2026
b894513
Outsource refactoring: wip
riccio82 Mar 12, 2026
160a719
Analysis page: wip
riccio82 Mar 13, 2026
2584450
Analysis page: wip
riccio82 Mar 13, 2026
e1e4bb5
Analysis page: wip
riccio82 Mar 13, 2026
7791a09
Analysis page: wip
riccio82 Mar 13, 2026
53994f4
Analysis page: wip
riccio82 Mar 16, 2026
c2dfb6c
My projects chunks and other stuff
piedicianni Mar 16, 2026
1bde4dd
Removed comment
piedicianni Mar 16, 2026
5361281
Job container and chunks
piedicianni Mar 17, 2026
497b02f
getSegmentsIdForQR refactoring
mauretto78 Mar 19, 2026
dab80e8
Segment history
mauretto78 Mar 23, 2026
5b10673
Segment history
mauretto78 Mar 24, 2026
72aca9d
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Mar 25, 2026
9b47e2e
QR: add segment history
riccio82 Mar 25, 2026
25bf443
feat: add file-type icon components
riccio82 Mar 26, 2026
ef55af7
πŸ› fix(icons): remove no-op clipPath with hardcoded id from FileTypeFo…
riccio82 Mar 26, 2026
b07d0eb
Update files icons
riccio82 Mar 26, 2026
f9d5c37
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Mar 26, 2026
0b36c3d
Remove old files image
riccio82 Mar 26, 2026
355d0d6
Fix tests
riccio82 Mar 26, 2026
279f2fa
Job table and job menu
piedicianni Mar 20, 2026
6d082e9
Job progress bar improvements
piedicianni Mar 27, 2026
73f48c5
Fix
piedicianni Mar 27, 2026
572c342
Merge branch 'develop' into update-design
piedicianni Mar 27, 2026
8ba3551
Some test fix
piedicianni Mar 27, 2026
246ef9b
Update QR
riccio82 Mar 27, 2026
cdee7a8
My projects css and so on
piedicianni Mar 31, 2026
4231e74
Header members filter, search project and status filter
piedicianni Apr 1, 2026
35e1a7a
Fix
piedicianni Apr 1, 2026
67cb178
New header and other stuff
piedicianni Apr 2, 2026
ec82ea7
Merge remote-tracking branch 'origin' into update-design
riccio82 Apr 7, 2026
913984a
New files icon
riccio82 Apr 7, 2026
a358731
Filters improvements and empty state
piedicianni Apr 7, 2026
d537960
Some tests fix
piedicianni Apr 13, 2026
b472c7b
Outsource info
piedicianni Apr 13, 2026
b199032
Outsource translator
piedicianni Apr 14, 2026
345e9ca
Merge remote-tracking branch 'origin/develop' into update-design
riccio82 Apr 22, 2026
e25384c
Update public/css/sass/components/common/Checkbox.scss
riccio82 Apr 22, 2026
be2e92c
fix: css fix
riccio82 Apr 22, 2026
fa563d2
Update public/css/sass/modals/split_modal.scss
riccio82 Apr 22, 2026
6df9b29
fix: css qaComponent
riccio82 Apr 22, 2026
74f5f49
Notifications
piedicianni Apr 23, 2026
63c1dae
Removing total_time_to_edit field from chunk API representations
mauretto78 May 28, 2026
5bfce7e
Merge branch 'update-design' of github.com:matecat/MateCat into updat…
mauretto78 May 28, 2026
fd9b8d2
Merge remote-tracking branch 'origin' into update-design
Jun 8, 2026
81927c3
πŸ› fix(css): align color variables with new naming scheme
Jun 8, 2026
4039aee
πŸ› fix(settings-panel): correct context module import paths
Jun 8, 2026
e574af5
πŸ› fix(css): replace invalid :global() pseudo-class in Button component
Jun 8, 2026
30c9431
♻️ refactor(settings-panel): shorten API import paths in QualityFrame…
Jun 8, 2026
b0e22a0
πŸ”§ chore: update submodules
Jun 8, 2026
6331040
Fixed TranslationVersionDao
mauretto78 Jun 8, 2026
fbac24e
Merge remote-tracking branch 'origin' into update-design
riccio82 Jun 9, 2026
f4ede36
πŸ› fix(tests): add BUTTON_MODE to NewProject Button mock
riccio82 Jun 9, 2026
0214704
πŸ› fix(quality-report): show loading spinner only during segment fetch…
riccio82 Jun 9, 2026
252c077
Merge remote-tracking branch 'origin' into update-design
riccio82 Jun 9, 2026
93590a6
Fixed tests...
mauretto78 Jun 9, 2026
1fb0738
Merge branch 'update-design' of github.com:matecat/MateCat into updat…
mauretto78 Jun 9, 2026
088bc29
πŸ—οΈ build(css): add CSS architecture foundations (Phase 0)
riccio82 Jun 10, 2026
18b8124
Merge remote-tracking branch 'origin' into css-architecture
riccio82 Jun 11, 2026
4950caf
πŸ”§ chore: update docs
riccio82 Jun 11, 2026
9f7ae41
✨ feat(css): migrate 6 components to CSS Modules (Phase 1)
riccio82 Jun 11, 2026
8977969
✨ feat(css): migrate CookieConsent to CSS Module
riccio82 Jun 11, 2026
454f384
πŸ“ docs(css): move CSS-ARCHITECTURE.md to MateCat-docs submodule
riccio82 Jun 11, 2026
977176f
♻️ refactor(css): replace mergeClassNames with classnames + fix jest …
riccio82 Jun 11, 2026
066d54e
πŸ”€ merge(css): CSS architecture refactoring (Phase 0 + Phase 1)
riccio82 Jun 11, 2026
d2db84b
πŸ› fix(build): inject stylesheets in <head> + fix AnalyzeHeader TDZ error
riccio82 Jun 12, 2026
ed7fa22
Merge branch 'develop' of github.com:matecat/MateCat into update-design
riccio82 Jun 16, 2026
52e7c5e
Merge remote-tracking branch 'origin' into css-architecture
riccio82 Jun 16, 2026
7ae5a83
πŸ”§ chore: update yarn.lock
riccio82 Jun 16, 2026
5f3637b
Merge branch 'update-design' into css-architecture
riccio82 Jun 16, 2026
d7154cf
✨ feat(css): migrate Badge, NumericStepper, FilenameLabel to CSS Modules
riccio82 Jun 16, 2026
4ec0735
✨ feat(css): migrate Switch, Input, Popover, ProgressBar, Checkbox to…
riccio82 Jun 16, 2026
fe24255
πŸ”§ chore(css): clean up common-components.scss + update lint baseline …
riccio82 Jun 16, 2026
68edcbe
♻️ refactor(segments-filter): modernize component + flatten SCSS
riccio82 Jun 16, 2026
7d8488c
♻️ refactor(quality-report): flatten SCSS + convert class components
riccio82 Jun 16, 2026
371d35c
♻️ refactor(css): flatten nesting in search, common-modals, issuesCon…
riccio82 Jun 16, 2026
398d60a
♻️ refactor(css): flatten nesting in _nav-bar.scss _nav-bar.scss upl…
riccio82 Jun 16, 2026
015677d
πŸ”§ chore: update submodule
riccio82 Jun 17, 2026
0eb5258
♻️ refactor(css): migrate Accordion and SegmentedControl to CSS Modules
riccio82 Jun 17, 2026
540f0c4
πŸ”§ chore: update submodule
riccio82 Jun 17, 2026
d406fa6
♻️ refactor(css): flatten max-nesting-depth violations in global SCSS…
riccio82 Jun 18, 2026
013f8a2
Merge remote-tracking branch 'origin' into css-architecture
riccio82 Jun 22, 2026
0566731
πŸ”§ chore: update yarn.lock
riccio82 Jun 22, 2026
d049051
✨ feat(common): migrate JobProgressBar to CSS Modules
riccio82 Jun 22, 2026
f90ecd0
✨ feat(common): add JobProgressBar.module.scss
riccio82 Jun 22, 2026
4f2dcc3
πŸ”§ chore: update MateCat-docs submodule
riccio82 Jun 22, 2026
0ffea61
πŸ”§ chore: update MateCat-docs submodule
riccio82 Jun 22, 2026
19bf99c
πŸ”§ chore: update submodule
riccio82 Jun 26, 2026
6b962bf
πŸ”€ chore: merge origin/develop into update-design
riccio82 Jun 26, 2026
0e24fca
♻️ refactor: replace semantic-ui-react Popup with in-house Tooltip/Co…
riccio82 Jun 26, 2026
37da0ab
πŸ”§ chore: bump aligner submodule (semantic-ui-react removal)
riccio82 Jun 26, 2026
573fc58
♻️ refactor(analyze): replace Semantic inline loader with scoped .inl…
riccio82 Jun 30, 2026
d11daea
♻️ refactor(labels): replace Semantic UI cancel/status-dot labels wit…
riccio82 Jun 30, 2026
13e0158
♻️ refactor(avatars): replace Semantic UI circular/avatar image classes
riccio82 Jun 30, 2026
ffb1088
♻️ refactor(buttons): replace Semantic UI button classes with project…
riccio82 Jun 30, 2026
5ea257f
Merge remote-tracking branch 'origin' into semantic-ui-removal
riccio82 Jul 1, 2026
22a3f38
♻️ refactor(qr): fix QA button group β€” outline mode, merged borders, …
riccio82 Jul 1, 2026
30a40a0
πŸ”§ chore: update submodule
riccio82 Jul 1, 2026
e22b172
♻️ refactor(modals,search,outsource): remove Semantic UI layout/form …
riccio82 Jul 1, 2026
c967574
♻️ refactor(qr,outsource,modals): remove Semantic UI circular/accordi…
riccio82 Jul 1, 2026
099bbc2
♻️ refactor(scss): drop dead Semantic UI rules; rename mbc- β†’ comment…
riccio82 Jul 1, 2026
8192be0
♻️ refactor(scss): remove dead Semantic UI selectors and delete empty…
riccio82 Jul 1, 2026
fd954a2
♻️ refactor(scss): delete vendor_mc/semantic/, move link colors to co…
riccio82 Jul 1, 2026
29fe1a4
♻️ refactor(icons): remove icomoon font, replace usages with SVG comp…
riccio82 Jul 1, 2026
ff3a33f
♻️ refactor(icons): add SVG replacements for removed icomoon icons
riccio82 Jul 1, 2026
6e81ebd
πŸ› fix(scss): remove stray brace left in NewProjectPage.scss after ico…
riccio82 Jul 1, 2026
35bbc34
♻️ refactor(icons): move icon components from components/icons to img…
riccio82 Jul 1, 2026
31b9dc4
Merge branch 'semantic-ui-removal', remote-tracking branch 'origin' i…
riccio82 Jul 1, 2026
76b5fc7
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 1, 2026
ac43587
πŸ”§ chore: update submodule
riccio82 Jul 1, 2026
a0b7c39
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 2, 2026
d889bb6
πŸ› fix: yarn.lock
riccio82 Jul 2, 2026
5ba01d0
πŸ› fix: yarn.lock
riccio82 Jul 2, 2026
46ddf7b
πŸ› fix(notifications): render notification markup as JSX instead of HT…
riccio82 Jul 2, 2026
af4a233
πŸ’„ style(settingsPanel): update h3 font size, drag handle dimensions a…
piedicianni Jul 6, 2026
d737bc5
πŸ’„ style(cattool): update split, bulk bar, search and comments UI; fix…
piedicianni Jul 7, 2026
d69ea6c
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 14, 2026
846a55b
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 14, 2026
7e85130
πŸ’„ style(reset): add CSS reset partial and apply it to all page entry …
riccio82 Jul 15, 2026
ecf7cea
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 16, 2026
b25a29f
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 16, 2026
7e51347
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 16, 2026
040c1fa
βœ… test: fix tests
riccio82 Jul 16, 2026
0922a3e
πŸ’„ style(cattool): fix stacked notification spacing, grey5 color, and …
riccio82 Jul 16, 2026
830d2be
πŸ’„ style(modals): fix instructions modal heading and accordion spacing…
riccio82 Jul 16, 2026
943f920
πŸ’„ style(quality-report): polish revision feedback, glossary search, a…
riccio82 Jul 16, 2026
7cc0dab
♻️ refactor(segments): use Button component for lock/split icons, dro…
riccio82 Jul 16, 2026
9e6902d
♻️ refactor(css): migrate from commons/colors to tokens/colors, remov…
riccio82 Jul 16, 2026
7e5eaa6
♻️ refactor(review): use Button component for close/action icons in r…
riccio82 Jul 16, 2026
bdb7a0c
✨ feat(segments): show warning icon in footer when client is disconne…
riccio82 Jul 16, 2026
a9b6b5a
πŸ’„ style(header): enlarge user menu avatar toggle button
riccio82 Jul 16, 2026
7fe5539
πŸ’„ style(modals): downgrade api key and google drive headings to h4
riccio82 Jul 16, 2026
3a3e957
πŸ”§ chore(nodejs): update yarn.lock
riccio82 Jul 16, 2026
17c39ad
πŸ”§ chore(icons): remove unused IconSortUp
riccio82 Jul 16, 2026
c7d3c91
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 20, 2026
3b71841
πŸ”§ chore: update design icons
riccio82 Jul 20, 2026
a523160
πŸ’„ style: update outsource style
riccio82 Jul 21, 2026
81d72b3
Merge remote-tracking branch 'origin' into update-design
riccio82 Jul 22, 2026
594c29b
πŸ”§ chore: update yarn.lock
riccio82 Jul 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.*
!/.gitignore
!/.stylelintrc.json
# IDE stuffs
.settings
.idea
Expand Down
111 changes: 111 additions & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"extends": ["stylelint-config-standard-scss"],
"plugins": ["stylelint-selector-bem-pattern"],
"rules": {
"max-nesting-depth": [
3,
{
"ignoreAtRules": ["media", "supports", "include", "each", "if", "else"],
"ignoreRules": ["/^&/"],
"severity": "warning"
}
],
"declaration-no-important": [
true,
{
"severity": "warning"
}
],
"selector-class-pattern": null,
"scss/at-rule-no-unknown": true,
"scss/dollar-variable-pattern": null,
"no-descending-specificity": null,
"color-function-notation": null,
"color-function-alias-notation": null,
"alpha-value-notation": null,
"shorthand-property-no-redundant-values": null,
"declaration-block-no-redundant-longhand-properties": null,
"value-keyword-case": null,
"rule-empty-line-before": null,
"at-rule-empty-line-before": null,
"comment-empty-line-before": null,
"comment-whitespace-inside": null,
"custom-property-empty-line-before": null,
"declaration-empty-line-before": null,
"custom-property-pattern": null,
"length-zero-no-unit": null,
"selector-pseudo-element-colon-notation": null,
"property-no-vendor-prefix": null,
"value-no-vendor-prefix": null,
"media-feature-range-notation": null,
"declaration-block-single-line-max-declarations": null,
"scss/double-slash-comment-whitespace-inside": null,
"scss/double-slash-comment-empty-line-before": null,
"function-url-quotes": null,
"property-no-deprecated": null,
"block-no-empty": null,
"declaration-block-no-duplicate-properties": null,
"selector-not-notation": null,
"font-family-name-quotes": null,
"selector-id-pattern": null,
"selector-no-vendor-prefix": null,
"scss/load-partial-extension": null,
"number-max-precision": null,
"font-family-no-missing-generic-family-keyword": null,
"selector-type-no-unknown": null,
"selector-attribute-quotes": null,
"property-no-unknown": null,
"no-irregular-whitespace": null,
"keyframes-name-pattern": null,
"declaration-property-value-keyword-no-deprecated": null,
"scss/dollar-variable-empty-line-before": null,
"scss/operator-no-unspaced": null,
"scss/dollar-variable-colon-space-after": null,
"scss/dollar-variable-colon-space-before": null,
"at-rule-no-vendor-prefix": null,
"media-feature-name-no-vendor-prefix": null,
"declaration-block-no-shorthand-property-overrides": null,
"media-feature-name-no-unknown": null,
"no-empty-source": null,
"color-hex-length": null,
"scss/load-no-partial-leading-underscore": null,
"scss/comment-no-empty": null
},
"overrides": [
{
"files": ["**/*.module.scss"],
"plugins": ["stylelint-selector-bem-pattern"],
"rules": {
"max-nesting-depth": 3,
"declaration-no-important": true,
"plugin/selector-bem-pattern": {
"preset": "bem",
"componentSelectors": {
"initial": "^\\.{componentName}(?:__[a-z][a-z0-9-]*)?(?:--[a-z][a-z0-9-]*)?$"
}
}
}
},
{
"files": [
"public/css/sass/style.scss",
"public/css/sass/commons/_manage.scss",
"public/css/sass/commons/_outsource.scss",
"public/css/sass/commons/_analyze.scss",
"public/css/sass/mbc-style.scss"
],
"rules": {
"max-nesting-depth": null,
"declaration-no-important": null
}
},
{
"files": ["public/css/sass/vendor_mc/**"],
"rules": {
"max-nesting-depth": null,
"declaration-no-important": null,
"no-duplicate-selectors": null
}
}
]
}
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ version:
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.

3. Object Code Incorporating Material from Library Header Files.
3. Object Code Incorporating Material from Library Header GoToIcon.

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes the LGPL license text (β€œLibrary Header Files”) into β€œLibrary Header GoToIcon.”, which appears unintended and alters the legal terms text. Licenses should typically remain verbatim. Please revert this line to the original license wording unless there is a deliberate, legally-reviewed reason to modify it.

Suggested change
3. Object Code Incorporating Material from Library Header GoToIcon.
3. Object Code Incorporating Material from Library Header Files.

Copilot uses AI. Check for mistakes.

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The license text appears to have been accidentally modified; this should match the canonical LGPL wording. Please revert this line to the original text to avoid altering license terms.

Suggested change
3. Object Code Incorporating Material from Library Header GoToIcon.
3. Object Code Incorporating Material from Library Header Files.

Copilot uses AI. Check for mistakes.

The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
Expand Down
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,7 @@ module.exports = {
'^.+\\.js$': 'babel-jest',
'.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css',
},
moduleNameMapper: {
'\\.module\\.(css|scss|sass|less)$': '<rootDir>/test-utils/cssModuleMock.js',
},
}
1 change: 1 addition & 0 deletions lib/Controller/API/V3/QualityReportControllerAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ private function _formatSegments(array $segments, array $ttlArray, array $filesI
$seg['ice_modified'] = $segment->ice_modified;
$seg['is_pre_translated'] = $segment->is_pre_translated;
$seg['issues'] = $segment->issues;
$seg['history'] = $segment->history;

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description focuses on the new segment history API field, but the PR also contains a very large cross-cutting UI redesign (dozens of SCSS changes, new components, deleted legacy styles, layout refactors). This makes the PR difficult to review and risky to deploy; consider updating the PR description to reflect both scopes or splitting into separate PRs (API vs. design system refactor).

Copilot uses AI. Check for mistakes.
$seg['last_revisions'] = $segment->last_revisions;
$seg['last_translation'] = $segment->last_translation;
$seg['locked'] = $segment->locked;
Expand Down
23 changes: 23 additions & 0 deletions lib/Model/QualityReport/HistoryElementStruct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Model\QualityReport;

use Model\DataAccess\AbstractDaoObjectStruct;
use Model\DataAccess\IDaoStruct;

/**
* @property int $id_segment
* @property string $translation
* @property int $version_number
* @property int $source_page
*/
class HistoryElementStruct extends AbstractDaoObjectStruct implements IDaoStruct
{
public int $id_segment;
public string $translation;
public int $version_number;
public ?int $source_page = null;
public ?string $status = null;
public ?string $create_date = null;
public ?string $creation_date = null;
}
1 change: 1 addition & 0 deletions lib/Model/QualityReport/QualityReportDao.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public function getIssuesBySegments(array $segments_id, int $job_id): array

$sql = "SELECT

issues.translation_version as translation_version,
issues.id_segment as segment_id,
issues.id as issue_id,
issues.create_date as issue_create_date,
Expand Down
55 changes: 54 additions & 1 deletion lib/Model/QualityReport/QualityReportSegmentModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ public function getSegmentsForQR(array $segment_ids, $isForUI = false)

$translationVersionDao = new TranslationVersionDao($this->database);
$all_events = $translationVersionDao->getAllRelevantEvents($segmentIds, $chunkId);
$history_events = $translationVersionDao->historyEvents($segment_ids, $chunkId);

$segments = [];

Expand All @@ -241,7 +242,8 @@ public function getSegmentsForQR(array $segment_ids, $isForUI = false)
$this->_commonSegmentAssignments($seg, $Filter, $featureSet, $this->chunk, $isForUI);
$this->_assignIssues($seg, $issues, $issue_comments);
$this->_assignComments($seg, $comments);
$this->_populateLastTranslationAndRevision($seg, $Filter, $all_events, $isForUI);
$this->_populateLastTranslationAndRevision($seg, $Filter, $all_events, $isForUI);
$this->_populateHistory($seg, $Filter, $history_events, $issues, $isForUI);

$seg->pee_translation_revise = $seg->getPEEBwtTranslationRevise();
$seg->pee_translation_suggestion = $seg->getPEEBwtTranslationSuggestion();
Expand All @@ -252,6 +254,57 @@ public function getSegmentsForQR(array $segment_ids, $isForUI = false)
return $segments;
}

/**
* Populates the history for a given quality report segment by organizing events and associated issues.
*
* @param QualityReportSegmentStruct $seg The segment structure where the history will be populated.
* @param MateCatFilter $Filter The filter used to process translations for UI rendering.
* @param HistoryElementStruct[] $events An array of SegmentEventsStruct objects representing the events related to the segment.
* @param ShapelessConcreteStruct[] $issues An array of issue objects to associate with the events, filtered by segment and version.
* @param bool $isForUI Indicates whether the translation should be processed for UI display purposes.
*
* @throws Exception
*
* @return void
*/
Comment on lines +257 to +269

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docblock states $events is an array of SegmentEventsStruct, but _populateHistory() actually expects HistoryElementStruct (and uses it in the array_filter callback/foreach). Update the PHPDoc to match the real type to avoid misleading IDE/static analysis.

Copilot uses AI. Check for mistakes.
protected function _populateHistory(
QualityReportSegmentStruct $seg,
MateCatFilter $Filter,
array $events = [],
array $issues = [],
bool $isForUI = false
): void
{
$elements = [];

$eventsForThisSegment = array_filter($events, function (HistoryElementStruct $event) use ($seg) {
return $event->id_segment == $seg->sid;
});

/** @var HistoryElementStruct $event */
foreach ($eventsForThisSegment as $event) {
$translation = ($isForUI) ? $Filter->fromLayer0ToLayer2($event->translation) : $event->translation;

$elements[] = [
'status' => $event->status,
'date' => $event->creation_date ?? $event->create_date,
'revision_number' => ReviewUtils::sourcePageToRevisionNumber($event->source_page),
'source_page' => $event->source_page,
'version_number' => $event->version_number,
'translation' => $translation,
'issues' => array_filter($issues, function ($issue) use ($event) {
return
$issue->deleted_at === null &&
$event->id_segment == $issue->segment_id &&
$event->version_number == $issue->translation_version
;
})
Comment on lines +295 to +301

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array_filter() preserves original array keys. When this nested issues list is JSON-encoded, non-sequential numeric keys can cause PHP to encode it as an object instead of an array, breaking the API shape (the PR description shows issues: [] as a JSON array). Wrap the filtered result with array_values(...) to guarantee a proper JSON array.

Suggested change
'issues' => array_filter($issues, function ($issue) use ($event) {
return
$issue->deleted_at === null &&
$event->id_segment == $issue->segment_id &&
$event->version_number == $issue->translation_version
;
})
'issues' => array_values(array_filter($issues, function ($issue) use ($event) {
return
$issue->deleted_at === null &&
$event->id_segment == $issue->segment_id &&
$event->version_number == $issue->translation_version
;
}))

Copilot uses AI. Check for mistakes.
];
}
Comment on lines +285 to +303

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array_filter($issues, ...) runs for every history event, making history building O(events Γ— issues). If segments can have many events/issues, consider indexing issues once (e.g., by [segment_id][translation_version]) before the loop, then do O(1) lookups per event.

Copilot uses AI. Check for mistakes.

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description states the history is a chronological audit trail, but historyEvents() does not enforce a stable ordering across the UNION, and _populateHistory does not sort. To guarantee chronology, explicitly sort $elements by the computed 'date' (ascending) or add a deterministic ORDER BY in the SQL (and ensure the date column is consistently named/typed).

Suggested change
usort($elements, function (array $left, array $right) {
$leftDate = (string)($left['date'] ?? '');
$rightDate = (string)($right['date'] ?? '');
if ($leftDate !== $rightDate) {
return strcmp($leftDate, $rightDate);
}
$leftVersion = (int)($left['version_number'] ?? 0);
$rightVersion = (int)($right['version_number'] ?? 0);
if ($leftVersion !== $rightVersion) {
return $leftVersion <=> $rightVersion;
}
$leftRevision = (int)($left['revision_number'] ?? 0);
$rightRevision = (int)($right['revision_number'] ?? 0);
if ($leftRevision !== $rightRevision) {
return $leftRevision <=> $rightRevision;
}
return strcmp((string)($left['source_page'] ?? ''), (string)($right['source_page'] ?? ''));
});

Copilot uses AI. Check for mistakes.
$seg->history = $elements;
}

/**
* @return ChunkReviewStruct[]
* @throws Exception
Expand Down
6 changes: 6 additions & 0 deletions lib/Model/QualityReport/QualityReportSegmentStruct.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Matecat\SubFiltering\MateCatFilter;
use Model\DataAccess\AbstractDaoObjectStruct;
use Model\DataAccess\IDaoStruct;
use Model\DataAccess\ShapelessConcreteStruct;
use Model\FeaturesBase\FeatureSet;
use Model\Jobs\JobStruct;
use Utils\LQA\QA;
Expand Down Expand Up @@ -106,6 +107,11 @@ public function __construct(array $array_params = [])

protected string $tm_analysis_status;

/**
* @var array<mixed>
*/
public array $history = [];

Copilot AI Apr 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description focuses on adding history to the quality-report segments endpoint, but the PR also includes a very large cross-app Sass redesign (new tokens, layout, header/dashboard/job containers, deleted/renamed styles). Consider splitting the backend API change (history) and UI design refactor into separate PRs to keep reviewability and rollout risk manageable.

Copilot uses AI. Check for mistakes.

/**
* @return string
*/
Expand Down
2 changes: 0 additions & 2 deletions lib/Model/QualityReport/SegmentEventsStruct.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
*/
class SegmentEventsStruct extends AbstractDaoObjectStruct implements IDaoStruct
{

/**
* @var int
*/
Expand All @@ -37,5 +36,4 @@ class SegmentEventsStruct extends AbstractDaoObjectStruct implements IDaoStruct
* @var int
*/
protected int $source_page;

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Model\DataAccess\AbstractDaoObjectStruct;
use Model\DataAccess\ShapelessConcreteStruct;
use Model\Jobs\JobStruct;
use Model\QualityReport\HistoryElementStruct;
use Model\QualityReport\SegmentEventsStruct;
use Model\Translations\SegmentTranslationStruct;
use PDO;
Expand Down Expand Up @@ -248,6 +249,49 @@ public function getVersionsForRevision(int|string $id_job, int|string $id_segmen
);
}

/**
* @param array<int|string> $segments_id
* @param int $job_id
* @return array<HistoryElementStruct>
* @throws PDOException
*/
public function historyEvents(array $segments_id, int $job_id): array
{
$conn = $this->database->getConnection();
$prepare_str_segments_id = implode(', ', array_fill(0, count($segments_id), '?'));

$query = "SELECT
id_segment,
first_sv.version_number,
null as source_page,
null as status,
null as create_date,
first_sv.creation_date,
first_sv.translation
FROM segment_translation_versions first_sv WHERE id_segment IN ( $prepare_str_segments_id ) AND id_job = ? AND version_number = 0
UNION
SELECT ste.id_segment, ste.version_number, ste.source_page, ste.status, ste.create_date, stv.creation_date, stv.translation FROM segment_translation_events ste
INNER JOIN (
SELECT creation_date, id_segment, translation, version_number, id_job
FROM segment_translation_versions
WHERE id_segment IN ( $prepare_str_segments_id )
AND id_job = ?
UNION
SELECT null as creation_date, id_segment, translation, version_number, id_job
FROM segment_translations
WHERE id_segment IN ( $prepare_str_segments_id )
AND id_job = ?
) AS stv ON stv.version_number = ste.version_number AND stv.id_segment = ste.id_segment

WHERE ste.id_segment IN ( $prepare_str_segments_id ) GROUP BY version_number, source_page;";

Copilot AI Apr 22, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This GROUP BY version_number, source_page selects additional non-aggregated columns (e.g., status, translation, dates). In environments with ONLY_FULL_GROUP_BY enabled, this will fail at runtime; even when it runs, the chosen row per group is nondeterministic. Prefer SELECT DISTINCT with a clear row identity, or aggregate deterministically (e.g., MAX(create_date)/MAX(creation_date)) and/or include all selected columns in the GROUP BY.

Copilot uses AI. Check for mistakes.

$stmt = $conn->prepare($query);
$stmt->setFetchMode(PDO::FETCH_CLASS, HistoryElementStruct::class);
$stmt->execute(array_merge($segments_id, [$job_id], $segments_id, [$job_id], $segments_id, [$job_id], $segments_id));
Comment on lines +284 to +290

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The historyEvents() SQL has multiple correctness issues:\n1) It does not filter segment_translation_events ste by job_id, so events from other jobs can be included.\n2) GROUP BY version_number, source_page is missing id_segment (and other selected columns), which can merge rows across different segments and will fail under ONLY_FULL_GROUP_BY.\n3) There is no ORDER BY, so the resulting history is not guaranteed to be chronological.\nSuggested fix: add ste.id_job = ? and include ste.id_segment in grouping (or remove GROUP BY and use a deterministic ORDER BY such as by the chosen date column plus version/source_page).

Suggested change
) AS stv ON stv.version_number = ste.version_number AND stv.id_segment = ste.id_segment
WHERE ste.id_segment IN ( $prepare_str_segments_id ) GROUP BY version_number, source_page;";
$stmt = $db->prepare($query);
$stmt->setFetchMode(PDO::FETCH_CLASS, HistoryElementStruct::class);
$stmt->execute(array_merge($segments_id, [$job_id], $segments_id, [$job_id], $segments_id, [$job_id], $segments_id));
) AS stv ON stv.version_number = ste.version_number AND stv.id_segment = ste.id_segment AND stv.id_job = ste.id_job
WHERE ste.id_segment IN ( $prepare_str_segments_id ) AND ste.id_job = ?
ORDER BY id_segment, COALESCE(create_date, creation_date), version_number, source_page;";
$stmt = $db->prepare($query);
$stmt->setFetchMode(PDO::FETCH_CLASS, HistoryElementStruct::class);
$stmt->execute(array_merge($segments_id, [$job_id], $segments_id, [$job_id], $segments_id, [$job_id], $segments_id, [$job_id]));

Copilot uses AI. Check for mistakes.

return $stmt->fetchAll();
}

/**
* @param list<int> $segments_id
* @param int $job_id
Expand Down Expand Up @@ -279,7 +323,7 @@ public function getAllRelevantEvents(array $segments_id, int $job_id): array
AND id_job = ?
) AS stv
RIGHT JOIN (
SELECT MAX(version_number) AS version_number, ste.id_segment, ste.source_page
SELECT MAX(version_number) AS version_number, ste.id, ste.id_segment, ste.source_page

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This SELECT mixes an aggregate (MAX(version_number)) with non-aggregated columns (ste.id, ste.id_segment, ste.source_page). If the query groups by segment/page, ste.id will be nondeterministic (or rejected with ONLY_FULL_GROUP_BY). Consider either removing ste.id from the projection or selecting an aggregate like MAX(ste.id) AS id that matches the grouping semantics.

Suggested change
SELECT MAX(version_number) AS version_number, ste.id, ste.id_segment, ste.source_page
SELECT MAX(version_number) AS version_number, ste.id_segment, ste.source_page

Copilot uses AI. Check for mistakes.
FROM segment_translation_events ste
WHERE id_segment IN ( $prepare_str_segments_id )
AND ste.id_job = ?
Expand Down
4 changes: 3 additions & 1 deletion lib/Utils/Engines/GoogleTranslate.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ protected function _decode(mixed $rawValue, array $parameters = [], $function =
return $this->_composeMTResponseAsMatch($all_args[1]['text'], $decoded);
} else {
$engineResponse = json_decode($decoded['error']['response'], true);
throw new Exception($engineResponse['error']['message'], $engineResponse['error']['code']);
$errorMessage = $engineResponse['error']['message'] ?? 'Unknown error';
$errorCode = $engineResponse['error']['code'] ?? 500;
throw new Exception($errorMessage, $errorCode);
}
} else {
throw new Exception($rawValue['error']['message'], 500); // already decoded in case of error
Expand Down
1 change: 0 additions & 1 deletion lib/View/API/V3/Json/Chunk.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ public function renderItem(JobStruct $chunk, ProjectStruct $project, FeatureSet
'subject_printable' => $subjectsHashMap[$chunk->subject],
'owner' => $chunk->owner,
'time_to_edit' => $this->getTimeToEditArray((int)$chunk->id),
'total_time_to_edit' => $chunk->total_time_to_edit,
'avg_post_editing_effort' => (float)$chunk->avg_post_editing_effort,
'open_threads_count' => (int)$chunk->getOpenThreadsCount(new CommentDao($this->database)),
'created_at' => Utils::api_timestamp($chunk->create_date),
Expand Down
Loading
Loading