2024-10-28 21:15:05 +01:00
< script lang = "ts" setup >
2022-09-27 07:22:19 +02:00
import DiffFileTreeItem from './DiffFileTreeItem.vue' ;
2024-07-07 17:32:30 +02:00
import { loadMoreFiles } from '../features/repo-diff.ts' ;
import { toggleElem } from '../utils/dom.ts' ;
import { diffTreeStore } from '../modules/stores.ts' ;
import { setFileFolding } from '../features/file-fold.ts' ;
2024-10-28 21:15:05 +01:00
import { computed , onMounted , onUnmounted } from 'vue' ;
2022-09-27 07:22:19 +02:00
const LOCAL _STORAGE _KEY = 'diff_file_tree_visible' ;
2024-10-28 21:15:05 +01:00
const store = diffTreeStore ( ) ;
const fileTree = computed ( ( ) => {
const result = [ ] ;
for ( const file of store . files ) {
// Split file into directories
const splits = file . Name . split ( '/' ) ;
let index = 0 ;
let parent = null ;
let isFile = false ;
for ( const split of splits ) {
index += 1 ;
// reached the end
if ( index === splits . length ) {
isFile = true ;
2022-09-27 07:22:19 +02:00
}
2024-10-28 21:15:05 +01:00
let newParent = {
name : split ,
children : [ ] ,
isFile ,
} as {
name : string ,
children : any [ ] ,
isFile : boolean ,
file ? : any ,
2022-09-27 07:22:19 +02:00
} ;
2024-10-28 21:15:05 +01:00
if ( isFile === true ) {
newParent . file = file ;
}
if ( parent ) {
// check if the folder already exists
const existingFolder = parent . children . find (
( x ) => x . name === split ,
) ;
if ( existingFolder ) {
newParent = existingFolder ;
} else {
parent . children . push ( newParent ) ;
}
} else {
const existingFolder = result . find ( ( x ) => x . name === split ) ;
if ( existingFolder ) {
newParent = existingFolder ;
} else {
result . push ( newParent ) ;
}
}
parent = newParent ;
}
}
const mergeChildIfOnlyOneDir = ( entries ) => {
for ( const entry of entries ) {
if ( entry . children ) {
mergeChildIfOnlyOneDir ( entry . children ) ;
2023-04-12 15:06:39 +08:00
}
2024-10-28 21:15:05 +01:00
if ( entry . children . length === 1 && entry . children [ 0 ] . isFile === false ) {
// Merge it to the parent
entry . name = ` ${ entry . name } / ${ entry . children [ 0 ] . name } ` ;
entry . children = entry . children [ 0 ] . children ;
}
}
} ;
// Merge folders with just a folder as children in order to
// reduce the depth of our tree.
mergeChildIfOnlyOneDir ( result ) ;
return result ;
} ) ;
onMounted ( ( ) => {
// Default to true if unset
store . fileTreeIsVisible = localStorage . getItem ( LOCAL _STORAGE _KEY ) !== 'false' ;
document . querySelector ( '.diff-toggle-file-tree-button' ) . addEventListener ( 'click' , toggleVisibility ) ;
hashChangeListener ( ) ;
window . addEventListener ( 'hashchange' , hashChangeListener ) ;
} ) ;
onUnmounted ( ( ) => {
document . querySelector ( '.diff-toggle-file-tree-button' ) . removeEventListener ( 'click' , toggleVisibility ) ;
window . removeEventListener ( 'hashchange' , hashChangeListener ) ;
} ) ;
function hashChangeListener ( ) {
store . selectedItem = window . location . hash ;
expandSelectedFile ( ) ;
}
function expandSelectedFile ( ) {
// expand file if the selected file is folded
if ( store . selectedItem ) {
const box = document . querySelector ( store . selectedItem ) ;
const folded = box ? . getAttribute ( 'data-folded' ) === 'true' ;
if ( folded ) setFileFolding ( box , box . querySelector ( '.fold-file' ) , false ) ;
}
}
function toggleVisibility ( ) {
updateVisibility ( ! store . fileTreeIsVisible ) ;
}
function updateVisibility ( visible ) {
store . fileTreeIsVisible = visible ;
localStorage . setItem ( LOCAL _STORAGE _KEY , store . fileTreeIsVisible ) ;
updateState ( store . fileTreeIsVisible ) ;
}
function updateState ( visible ) {
const btn = document . querySelector ( '.diff-toggle-file-tree-button' ) ;
const [ toShow , toHide ] = btn . querySelectorAll ( '.icon' ) ;
const tree = document . querySelector ( '#diff-file-tree' ) ;
const newTooltip = btn . getAttribute ( visible ? 'data-hide-text' : 'data-show-text' ) ;
btn . setAttribute ( 'data-tooltip-content' , newTooltip ) ;
toggleElem ( tree , visible ) ;
toggleElem ( toShow , ! visible ) ;
toggleElem ( toHide , visible ) ;
}
function loadMoreData ( ) {
loadMoreFiles ( store . linkLoadMore ) ;
}
2022-09-27 07:22:19 +02:00
< / script >
2024-10-28 21:15:05 +01:00
2023-09-02 16:59:07 +02:00
< template >
2023-10-21 12:38:19 +02:00
< div v-if = "store.fileTreeIsVisible" class="diff-file-tree-items" >
2023-09-02 16:59:07 +02:00
<!-- only render the tree if we 're visible. in many cases this is something that doesn' t change very often -- >
< DiffFileTreeItem v-for = "item in fileTree" :key="item.name" :item = "item" / >
Migrate margin and padding helpers to tailwind (#30043)
This will conclude the refactor of 1:1 class replacements to tailwind,
except `gt-hidden`. Commands ran:
```bash
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-0#tw-$1$2-0#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-1#tw-$1$2-0.5#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-2#tw-$1$2-1#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-3#tw-$1$2-2#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-4#tw-$1$2-4#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-5#tw-$1$2-8#g' {web_src/js,templates,routers,services}/**/*
```
2024-03-24 17:42:49 +01:00
< div v-if = "store.isIncomplete" class="tw-pt-1" >
2023-09-02 16:59:07 +02:00
< a : class = "['ui', 'basic', 'tiny', 'button', store.isLoadingNewData ? 'disabled' : '']" @click.stop ="loadMoreData" > { { store . showMoreMessage } } < / a >
< / div >
< / div >
< / template >
2024-10-28 21:15:05 +01:00
2023-10-21 12:38:19 +02:00
< style scoped >
. diff - file - tree - items {
display : flex ;
flex - direction : column ;
gap : 1 px ;
margin - right : .5 rem ;
}
< / style >