|
|
@@ -853,7 +853,7 @@ class HTMLReportCreator(ReportCreator):
|
|
853
|
853
|
binarypath = os.path.dirname(os.path.abspath(__file__))
|
|
854
|
854
|
secondarypath = os.path.join(binarypath, '..', 'share', 'gitstats')
|
|
855
|
855
|
basedirs = [binarypath, secondarypath, '/usr/share/gitstats']
|
|
856
|
|
- for file in (conf['style'], 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif'):
|
|
|
856
|
+ for file in (conf['style'], 'sortable.js', 'arrow-up.gif', 'arrow-down.gif', 'arrow-none.gif', 'tailwind.json'):
|
|
857
|
857
|
for base in basedirs:
|
|
858
|
858
|
src = base + '/' + file
|
|
859
|
859
|
if os.path.exists(src):
|
|
|
@@ -866,21 +866,47 @@ class HTMLReportCreator(ReportCreator):
|
|
866
|
866
|
# General
|
|
867
|
867
|
format = '%Y-%m-%d %H:%M:%S'
|
|
868
|
868
|
|
|
869
|
|
- general_content = ['<h1 class="text-3xl font-bold underline">GitStats - %s</h1>' % data.projectname]
|
|
|
869
|
+ # general_content = ['<h1 class="text-3xl font-bold underline">GitStats - %s</h1>' % data.projectname]
|
|
|
870
|
+
|
|
|
871
|
+ general_content = []
|
|
|
872
|
+
|
|
|
873
|
+
|
|
|
874
|
+ tiles = '\n'.join([
|
|
|
875
|
+ self.tilesItemStat(title='Project name', info=data.projectname),
|
|
|
876
|
+ self.tilesItemStat(title='Generated', info=datetime.datetime.now().strftime(format)),
|
|
|
877
|
+ self.tilesItemStat(title='Report Period', info=f'{data.getFirstCommitDate().strftime(format)} to {data.getLastCommitDate().strftime(format)}'),
|
|
|
878
|
+ ])
|
|
|
879
|
+
|
|
|
880
|
+ cards = '\n'.join([
|
|
|
881
|
+ self.cardItemStat(title='Branches', count=data.total_branches),
|
|
|
882
|
+ self.cardItemStat(title='Tags', count=data.total_tags),
|
|
|
883
|
+ self.cardItemStat(title='Age', count=f'{data.getCommitDeltaDays():.1f} days'),
|
|
|
884
|
+ self.cardItemStat(title='Active days', count=f'{len(data.getActiveDays())}', stat=f'{(100.0 * len(data.getActiveDays()) / data.getCommitDeltaDays()):3.2f}%', arrow='up'),
|
|
|
885
|
+ self.cardItemStat(title='Total files', count=data.getTotalFiles()),
|
|
|
886
|
+ self.cardItemStat(title='Total LOC', count=data.getTotalLOC()),
|
|
|
887
|
+ self.cardItemStat(title='Total lines added', count=data.total_lines_added, stat=f'{((data.total_lines_added/data.getTotalLOC())*100):.2f}%', arrow='up'),
|
|
|
888
|
+ self.cardItemStat(title='Total lines removed', count=data.total_lines_removed, stat=f'{((data.total_lines_removed/data.getTotalLOC())*100):.2f}%', arrow='up'),
|
|
|
889
|
+ self.cardItemStat(title='Total commits', count=data.getTotalCommits(), stat=f'{(float(data.getTotalCommits()) / len(data.getActiveDays())):.1f}', arrow='up'),
|
|
|
890
|
+ self.cardItemStat(title='Authors', count=data.getTotalAuthors(), stat=f'{((1.0 * data.getTotalCommits()) / data.getTotalAuthors()):.1f}', arrow='up'),
|
|
|
891
|
+ ])
|
|
|
892
|
+
|
|
|
893
|
+ general_content.append(f'<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">{tiles}</div>')
|
|
|
894
|
+
|
|
|
895
|
+ general_content.append(f'<div class="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6 xl:grid-cols-4 2xl:gap-7.5">{cards}</div>')
|
|
870
|
896
|
|
|
871
|
|
- general_content.append('<div><div class="card-body"><dl>')
|
|
872
|
|
- general_content.append('<dt>Project name</dt><dd>%s (%s branches, %s tags)</dd>' % (data.projectname, data.total_branches, data.total_tags))
|
|
873
|
|
- general_content.append('<dt>Generated</dt><dd>%s (in %d seconds)</dd>' % (datetime.datetime.now().strftime(format), time.time() - data.getStampCreated()))
|
|
874
|
|
- general_content.append('<dt>Generator</dt><dd><a href="http://gitstats.sourceforge.net/">GitStats</a> (version %s), %s, %s</dd>' % (getversion(), getgitversion(), getgnuplotversion()))
|
|
875
|
|
- general_content.append('<dt>Report Period</dt><dd>%s to %s</dd>' % (data.getFirstCommitDate().strftime(format), data.getLastCommitDate().strftime(format)))
|
|
876
|
|
- general_content.append('<dt>Age</dt><dd>%d days, %d active days (%3.2f%%)</dd>' % (data.getCommitDeltaDays(), len(data.getActiveDays()), (100.0 * len(data.getActiveDays()) / data.getCommitDeltaDays())))
|
|
877
|
|
- general_content.append('<dt>Total Files</dt><dd>%s</dd>' % data.getTotalFiles())
|
|
878
|
|
- general_content.append('<dt>Total Lines of Code</dt><dd>%s (%d added, %d removed)</dd>' % (data.getTotalLOC(), data.total_lines_added, data.total_lines_removed))
|
|
879
|
|
- general_content.append('<dt>Total Commits</dt><dd>%s (average %.1f commits per active day, %.1f per all days)</dd>' % (data.getTotalCommits(), float(data.getTotalCommits()) / len(data.getActiveDays()), float(data.getTotalCommits()) / data.getCommitDeltaDays()))
|
|
880
|
|
- general_content.append('<dt>Authors</dt><dd>%s (average %.1f commits per author)</dd>' % (data.getTotalAuthors(), (1.0 * data.getTotalCommits()) / data.getTotalAuthors()))
|
|
881
|
|
- general_content.append('</dl></div></div>')
|
|
|
897
|
+ # general_content.append('<div><div class="card-body"><dl>')
|
|
|
898
|
+ # general_content.append('<dt>Project name</dt><dd>%s (%s branches, %s tags)</dd>' % (data.projectname, data.total_branches, data.total_tags))
|
|
|
899
|
+ # general_content.append('<dt>Generated</dt><dd>%s (in %d seconds)</dd>' % (datetime.datetime.now().strftime(format), time.time() - data.getStampCreated()))
|
|
|
900
|
+ # general_content.append('<dt>Generator</dt><dd><a href="http://gitstats.sourceforge.net/">GitStats</a> (version %s), %s, %s</dd>' % (getversion(), getgitversion(), getgnuplotversion()))
|
|
|
901
|
+ # general_content.append('<dt>Report Period</dt><dd>%s to %s</dd>' % (data.getFirstCommitDate().strftime(format), data.getLastCommitDate().strftime(format)))
|
|
|
902
|
+ # general_content.append('<dt>Age</dt><dd>%d days, %d active days (%3.2f%%)</dd>' % (data.getCommitDeltaDays(), len(data.getActiveDays()), (100.0 * len(data.getActiveDays()) / data.getCommitDeltaDays())))
|
|
|
903
|
+ # general_content.append('<dt>Total Files</dt><dd>%s</dd>' % data.getTotalFiles())
|
|
|
904
|
+ # general_content.append('<dt>Total Lines of Code</dt><dd>%s (%d added, %d removed)</dd>' % (data.getTotalLOC(), data.total_lines_added, data.total_lines_removed))
|
|
|
905
|
+ # general_content.append('<dt>Total Commits</dt><dd>%s (average %.1f commits per active day, %.1f per all days)</dd>' % (data.getTotalCommits(), float(data.getTotalCommits()) / len(data.getActiveDays()), float(data.getTotalCommits()) / data.getCommitDeltaDays()))
|
|
|
906
|
+ # general_content.append('<dt>Authors</dt><dd>%s (average %.1f commits per author)</dd>' % (data.getTotalAuthors(), (1.0 * data.getTotalCommits()) / data.getTotalAuthors()))
|
|
|
907
|
+ # general_content.append('</dl></div></div>')
|
|
882
|
908
|
|
|
883
|
|
- self.printPage(general_content, f'{path}/index.html', "FRONT'S STATS")
|
|
|
909
|
+ self.printPage(general_content, f'{path}/index.html', f"{data.projectname}'S STATS")
|
|
884
|
910
|
|
|
885
|
911
|
###
|
|
886
|
912
|
# activity.html
|
|
|
@@ -1404,7 +1430,7 @@ class HTMLReportCreator(ReportCreator):
|
|
1404
|
1430
|
lines_content.append('<tr><th>%s</th><td style="background-color: rgb(%d, 0, 0)">%d</td></tr>' % (i, r, commits))
|
|
1405
|
1431
|
lines_content.append('</tr></table>')
|
|
1406
|
1432
|
|
|
1407
|
|
- self.printPage(lines_content, f'{path}/tags.html', title='Lines')
|
|
|
1433
|
+ self.printPage(lines_content, f'{path}/lines.html', title='Lines')
|
|
1408
|
1434
|
|
|
1409
|
1435
|
###
|
|
1410
|
1436
|
# tags.html
|
|
|
@@ -1746,7 +1772,8 @@ plot """
|
|
1746
|
1772
|
|
|
1747
|
1773
|
def getHeader(self, title = None):
|
|
1748
|
1774
|
title = title or f'GitStats - {self.title}'
|
|
1749
|
|
- return """
|
|
|
1775
|
+ config = json.load(open('tailwind.json'))
|
|
|
1776
|
+ return '''
|
|
1750
|
1777
|
<head>
|
|
1751
|
1778
|
<meta charset="UTF-8">
|
|
1752
|
1779
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
|
@@ -1755,8 +1782,9 @@ plot """
|
|
1755
|
1782
|
<link rel="stylesheet" href="%s" type="text/css" />
|
|
1756
|
1783
|
<meta name="generator" content="GitStats %s" />
|
|
1757
|
1784
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
|
1785
|
+ <script> tailwind.config = %s </script>
|
|
1758
|
1786
|
</head>
|
|
1759
|
|
-""" % (title, conf['style'], getversion())
|
|
|
1787
|
+''' % (title, conf['style'], getversion(), json.dumps(config))
|
|
1760
|
1788
|
|
|
1761
|
1789
|
|
|
1762
|
1790
|
def getBody(self, content, title):
|
|
|
@@ -1775,37 +1803,131 @@ plot """
|
|
1775
|
1803
|
<!-- ===== Preloader End ===== -->
|
|
1776
|
1804
|
|
|
1777
|
1805
|
<!-- ===== Page Wrapper Start ===== -->
|
|
1778
|
|
- <div class="flex h-screen overflow-hidden antialiased text-gray-900 bg-gray-100 ">
|
|
|
1806
|
+ <div class="flex h-screen overflow-hidden">
|
|
1779
|
1807
|
{sidebar}
|
|
1780
|
1808
|
|
|
1781
|
1809
|
<!-- ===== Content Area Start ===== -->
|
|
1782
|
1810
|
<div class="relative flex flex-1 flex-col overflow-y-auto overflow-x-hidden">
|
|
1783
|
1811
|
{topBar}
|
|
1784
|
1812
|
<!-- Main content -->
|
|
1785
|
|
- <main class="p-2">{content}</main>
|
|
|
1813
|
+ <main>
|
|
|
1814
|
+ <div class="mx-auto max-w-screen-2xl p-4 md:p-6 2xl:p-10">
|
|
|
1815
|
+ {content}
|
|
|
1816
|
+ </div>
|
|
|
1817
|
+ </main>
|
|
1786
|
1818
|
</div>
|
|
1787
|
1819
|
<!-- ===== Content Area End ===== -->
|
|
1788
|
1820
|
|
|
1789
|
1821
|
</div>
|
|
1790
|
1822
|
<!-- ===== Page Wrapper End ===== -->
|
|
1791
|
1823
|
|
|
1792
|
|
- <script src="//unpkg.com/alpinejs" defer></script>
|
|
|
1824
|
+ <!-- <script src="//unpkg.com/alpinejs" defer></script> -->
|
|
|
1825
|
+ <!-- Alpine Plugins -->
|
|
|
1826
|
+ <script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/persist@3.13.0/dist/cdn.min.js"></script>
|
|
|
1827
|
+
|
|
|
1828
|
+ <!-- Alpine Core -->
|
|
|
1829
|
+ <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.13.0/dist/cdn.min.js"></script>
|
|
1793
|
1830
|
<script type="text/javascript" src="sortable.js"></script>
|
|
1794
|
1831
|
</body>
|
|
1795
|
1832
|
'''
|
|
|
1833
|
+ def tilesItemStat(self, title='', info='', icon=None, stat=None):
|
|
|
1834
|
+ if icon is not None:
|
|
|
1835
|
+ icon = f'''
|
|
|
1836
|
+<div class="flex items-center justify-center mb-6 md:mb-0">
|
|
|
1837
|
+ <span class="inline-flex justify-center items-center w-12 h-12 rounded-full text-emerald-500 bg-gray-50 dark:bg-slate-800 md:mr-6">
|
|
|
1838
|
+ <svg viewBox="0 0 24 24" width="24" height="24" class="inline-block">
|
|
|
1839
|
+ <path fill="currentColor" d="M15 15V17H18V20H20V17H23V15H20V12H18V15M14.97 11.61C14.85 10.28 13.59 8.97 12 9C10.3 9.03 9 10.3 9 12C9 13.7 10.3 14.94 12 15C12.38 15 12.77 14.92 13.14 14.77C13.41 13.67 13.86 12.63 14.97 11.61M13 16H7C7 14.9 6.11 14 5 14V10C6.11 10 7 9.11 7 8H17C17 9.11 17.9 10 19 10V10.06C19.67 10.06 20.34 10.18 21 10.4V6H3V18H13.32C13.1 17.33 13 16.66 13 16Z"></path>
|
|
|
1840
|
+ </svg>
|
|
|
1841
|
+ </span>
|
|
|
1842
|
+</div>'''
|
|
|
1843
|
+
|
|
|
1844
|
+ if stat is not None:
|
|
|
1845
|
+ stat = '''
|
|
|
1846
|
+<div class="text-center md:text-right space-y-2">
|
|
|
1847
|
+ <p class="text-sm text-gray-500">Home Loan Account</p>
|
|
|
1848
|
+ <div>
|
|
|
1849
|
+ <div class="inline-flex items-center capitalize leading-none text-xs border rounded-full py-1 px-3 bg-emerald-500 border-emerald-500 text-white">
|
|
|
1850
|
+ <span>deposit</span>
|
|
|
1851
|
+ </div>
|
|
|
1852
|
+ </div>
|
|
|
1853
|
+</div>'''
|
|
|
1854
|
+
|
|
|
1855
|
+ return f'''
|
|
|
1856
|
+<div class="rounded-sm border border-stroke bg-white px-7.5 py-6 shadow-default dark:border-strokedark dark:bg-boxdark">
|
|
|
1857
|
+ <div class="flex flex-col">
|
|
|
1858
|
+ <div class="flex-1 p-6">
|
|
|
1859
|
+ <div class="justify-between items-center block md:flex">
|
|
|
1860
|
+ <div class="flex items-center justify-center mb-6 md:mb-0">
|
|
|
1861
|
+ <div class="justify-start items-center block md:flex">
|
|
|
1862
|
+ {icon or ''}
|
|
|
1863
|
+ <div class="flex items-center justify-center">
|
|
|
1864
|
+ <div class="text-center text-black dark:text-white space-y-1 md:text-left md:mr-6">
|
|
|
1865
|
+ <h4 class="text-xl">{info}</h4>
|
|
|
1866
|
+ <p>{title}</p>
|
|
|
1867
|
+ </div>
|
|
|
1868
|
+ </div>
|
|
|
1869
|
+ </div>
|
|
|
1870
|
+ </div>
|
|
|
1871
|
+ <div class="flex items-center justify-center">
|
|
|
1872
|
+ {stat or ''}
|
|
|
1873
|
+ </div>
|
|
|
1874
|
+ </div>
|
|
|
1875
|
+ </div>
|
|
|
1876
|
+ </div>
|
|
|
1877
|
+</div>'''
|
|
|
1878
|
+
|
|
|
1879
|
+ def cardItemStat(self, count='$3.456K', title='Total views', stat = None, arrow= 'up', icon = None):
|
|
|
1880
|
+
|
|
|
1881
|
+ stat_html = ''
|
|
|
1882
|
+ if stat is not None:
|
|
|
1883
|
+ stat_html = f'''
|
|
|
1884
|
+<span class="flex items-center gap-1 text-sm font-medium text-meta-3">
|
|
|
1885
|
+ {stat}
|
|
|
1886
|
+ <svg class="fill-meta-3" width="10" height="11" viewBox="0 0 10 11" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
1887
|
+ {arrow is 'up' and '<path d="M4.35716 2.47737L0.908974 5.82987L5.0443e-07 4.94612L5 0.0848689L10 4.94612L9.09103 5.82987L5.64284 2.47737L5.64284 10.0849L4.35716 10.0849L4.35716 2.47737Z" fill=""></path>'}
|
|
|
1888
|
+ {arrow is 'down' and '<path d="M5.64284 7.69237L9.09102 4.33987L10 5.22362L5 10.0849L-8.98488e-07 5.22362L0.908973 4.33987L4.35716 7.69237L4.35716 0.0848701L5.64284 0.0848704L5.64284 7.69237Z" fill=""></path>'}
|
|
|
1889
|
+ </svg>
|
|
|
1890
|
+</span>'''
|
|
|
1891
|
+
|
|
|
1892
|
+ if icon is None:
|
|
|
1893
|
+ icon = '''
|
|
|
1894
|
+<svg class="fill-primary dark:fill-white" width="22" height="16" viewBox="0 0 22 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
|
1895
|
+ <path d="M11 15.1156C4.19376 15.1156 0.825012 8.61876 0.687512 8.34376C0.584387 8.13751 0.584387 7.86251 0.687512 7.65626C0.825012 7.38126 4.19376 0.918762 11 0.918762C17.8063 0.918762 21.175 7.38126 21.3125 7.65626C21.4156 7.86251 21.4156 8.13751 21.3125 8.34376C21.175 8.61876 17.8063 15.1156 11 15.1156ZM2.26876 8.00001C3.02501 9.27189 5.98126 13.5688 11 13.5688C16.0188 13.5688 18.975 9.27189 19.7313 8.00001C18.975 6.72814 16.0188 2.43126 11 2.43126C5.98126 2.43126 3.02501 6.72814 2.26876 8.00001Z" fill=""></path>
|
|
|
1896
|
+ <path d="M11 10.9219C9.38438 10.9219 8.07812 9.61562 8.07812 8C8.07812 6.38438 9.38438 5.07812 11 5.07812C12.6156 5.07812 13.9219 6.38438 13.9219 8C13.9219 9.61562 12.6156 10.9219 11 10.9219ZM11 6.625C10.2437 6.625 9.625 7.24375 9.625 8C9.625 8.75625 10.2437 9.375 11 9.375C11.7563 9.375 12.375 8.75625 12.375 8C12.375 7.24375 11.7563 6.625 11 6.625Z" fill=""></path>
|
|
|
1897
|
+</svg>'''
|
|
|
1898
|
+
|
|
|
1899
|
+ return f'''
|
|
|
1900
|
+<div class="rounded-sm border border-stroke bg-white px-7.5 py-6 shadow-default dark:border-strokedark dark:bg-boxdark">
|
|
|
1901
|
+ <div class="flex h-11.5 w-11.5 items-center justify-center rounded-full bg-meta-2 dark:bg-meta-4">
|
|
|
1902
|
+ {icon}
|
|
|
1903
|
+ </div>
|
|
|
1904
|
+
|
|
|
1905
|
+ <div class="mt-4 flex items-end justify-between">
|
|
|
1906
|
+ <div>
|
|
|
1907
|
+ <h4 class="text-title-md font-bold text-black dark:text-white">{count}</h4>
|
|
|
1908
|
+ <span class="text-sm font-medium">{title}</span>
|
|
|
1909
|
+ </div>
|
|
|
1910
|
+
|
|
|
1911
|
+ {stat_html}
|
|
|
1912
|
+ </div>
|
|
|
1913
|
+</div>'''
|
|
1796
|
1914
|
|
|
1797
|
1915
|
def getSideBar(self):
|
|
1798
|
1916
|
menu = ''.join([f'''
|
|
1799
|
|
-<a href="{href}"
|
|
1800
|
|
- class="flex items-center p-2 text-gray-500 transition-colors rounded-md dark:text-light hover:bg-primary-100 dark:hover:bg-primary"
|
|
1801
|
|
- role="button">
|
|
1802
|
|
- <span aria-hidden="true">
|
|
1803
|
|
- <svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
1804
|
|
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
1805
|
|
- </svg>
|
|
1806
|
|
- </span>
|
|
1807
|
|
- <span class="ml-2 text-sm">{label}</span>
|
|
1808
|
|
-</a>
|
|
|
1917
|
+<li>
|
|
|
1918
|
+ <a href="{href}"
|
|
|
1919
|
+ @click="selected = (selected === '{label}' ? '':'{label}')"
|
|
|
1920
|
+ :class="{{ 'bg-graydark dark:bg-meta-4': (selected === '{label}') }}"
|
|
|
1921
|
+ class="group relative flex items-center gap-2.5 rounded-sm px-4 py-2 font-medium text-bodydark1 duration-300 ease-in-out hover:bg-graydark dark:hover:bg-meta-4"
|
|
|
1922
|
+ role="button">
|
|
|
1923
|
+ <span aria-hidden="true">
|
|
|
1924
|
+ <svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
|
1925
|
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
|
|
|
1926
|
+ </svg>
|
|
|
1927
|
+ </span>
|
|
|
1928
|
+ <span class="ml-2 text-sm">{label}</span>
|
|
|
1929
|
+ </a>
|
|
|
1930
|
+</li>
|
|
1809
|
1931
|
''' for (label, href) in [
|
|
1810
|
1932
|
("General", "index.html"),
|
|
1811
|
1933
|
("Activity", "activity.html"),
|
|
|
@@ -1817,18 +1939,49 @@ plot """
|
|
1817
|
1939
|
|
|
1818
|
1940
|
return f'''
|
|
1819
|
1941
|
<!-- Sidebar -->
|
|
1820
|
|
-<aside class="flex-shrink-0 hidden w-64 bg-white border-r dark:border-primary-darker dark:bg-darker md:block">
|
|
1821
|
|
- <div class="flex flex-col h-full">
|
|
|
1942
|
+<aside :class="sidebarToggle ? 'translate-x-0' : '-translate-x-full'"
|
|
|
1943
|
+ @click.outside="sidebarToggle = false"
|
|
|
1944
|
+ class="absolute left-0 top-0 z-9999 flex h-screen w-72.5 flex-col overflow-y-hidden bg-black duration-300 ease-linear dark:bg-boxdark lg:static lg:translate-x-0 -translate-x-full">
|
|
|
1945
|
+
|
|
|
1946
|
+ <!-- SIDEBAR HEADER -->
|
|
|
1947
|
+ <div class="flex items-center justify-between gap-2 px-6 py-5.5 lg:py-6.5">
|
|
|
1948
|
+ <a href="index.html">
|
|
|
1949
|
+ <img src="https://demo.tailadmin.com/src/images/logo/logo.svg" alt="Logo" />
|
|
|
1950
|
+ </a>
|
|
|
1951
|
+
|
|
|
1952
|
+ <button
|
|
|
1953
|
+ class="block lg:hidden"
|
|
|
1954
|
+ @click.stop="sidebarToggle = !sidebarToggle"
|
|
|
1955
|
+ >
|
|
|
1956
|
+ <svg
|
|
|
1957
|
+ class="fill-current"
|
|
|
1958
|
+ width="20"
|
|
|
1959
|
+ height="18"
|
|
|
1960
|
+ viewBox="0 0 20 18"
|
|
|
1961
|
+ fill="none"
|
|
|
1962
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
1963
|
+ >
|
|
|
1964
|
+ <path
|
|
|
1965
|
+ d="M19 8.175H2.98748L9.36248 1.6875C9.69998 1.35 9.69998 0.825 9.36248 0.4875C9.02498 0.15 8.49998 0.15 8.16248 0.4875L0.399976 8.3625C0.0624756 8.7 0.0624756 9.225 0.399976 9.5625L8.16248 17.4375C8.31248 17.5875 8.53748 17.7 8.76248 17.7C8.98748 17.7 9.17498 17.625 9.36248 17.475C9.69998 17.1375 9.69998 16.6125 9.36248 16.275L3.02498 9.8625H19C19.45 9.8625 19.825 9.4875 19.825 9.0375C19.825 8.55 19.45 8.175 19 8.175Z"
|
|
|
1966
|
+ fill=""
|
|
|
1967
|
+ />
|
|
|
1968
|
+ </svg>
|
|
|
1969
|
+ </button>
|
|
|
1970
|
+ </div>
|
|
|
1971
|
+ <!-- SIDEBAR HEADER -->
|
|
|
1972
|
+
|
|
|
1973
|
+ <div class="no-scrollbar flex flex-col overflow-y-auto duration-300 ease-linear">
|
|
1822
|
1974
|
<!-- Sidebar links -->
|
|
1823
|
|
- <nav aria-label="Main" class="flex-1 px-2 py-4 space-y-2 overflow-y-hidden hover:overflow-y-auto">
|
|
1824
|
|
- {menu}
|
|
|
1975
|
+ <nav aria-label="Main" class="mt-5 px-4 py-4 lg:mt-9 lg:px-6" x-data="{{selected: $persist('General')}}">
|
|
|
1976
|
+ <div>
|
|
|
1977
|
+ <h3 class="mb-4 ml-4 text-sm font-medium text-bodydark2">MENU</h3>
|
|
|
1978
|
+ <ul class="mb-6 flex flex-col gap-1.5">
|
|
|
1979
|
+ {menu}
|
|
|
1980
|
+ </ul>
|
|
|
1981
|
+ </div>
|
|
1825
|
1982
|
</nav>
|
|
1826
|
1983
|
<!-- Sidebar footer -->
|
|
1827
|
|
- <div class="flex-shrink-0 px-2 py-4 space-y-2">
|
|
1828
|
|
- <button type="button" class="flex items-center justify-center w-full px-4 py-2 text-sm text-white rounded-md bg-blue hover:bg-primary-dark focus:outline-none focus:ring focus:ring-primary-dark focus:ring-offset-1 focus:ring-offset-white dark:focus:ring-offset-dark">
|
|
1829
|
|
- <span>Customize</span>
|
|
1830
|
|
- </button>
|
|
1831
|
|
- </div>
|
|
|
1984
|
+ <div class="flex-shrink-0 px-2 py-4 space-y-2"></div>
|
|
1832
|
1985
|
</div>
|
|
1833
|
1986
|
</aside>
|
|
1834
|
1987
|
'''
|
|
|
@@ -1836,11 +1989,107 @@ plot """
|
|
1836
|
1989
|
def getTopBar(self, title):
|
|
1837
|
1990
|
return f'''
|
|
1838
|
1991
|
<!-- Navbar -->
|
|
1839
|
|
-<header class="sticky top-0 z-999 flex w-full bg-white drop-shadow-1">
|
|
|
1992
|
+<header class="sticky top-0 z-999 flex w-full bg-white drop-shadow-1 dark:bg-boxdark dark:drop-shadow-none">
|
|
1840
|
1993
|
<div class="flex flex-grow items-center justify-between px-4 py-4 shadow-2 md:px-6 2xl:px-11">
|
|
1841
|
|
- <a href="#" class="inline-block text-2xl font-bold tracking-wider uppercase text-primary-dark">{title}</a>
|
|
|
1994
|
+ <div class="flex items-center gap-2 sm:gap-4 lg:hidden">
|
|
|
1995
|
+ <!-- Hamburger Toggle BTN -->
|
|
|
1996
|
+ <button
|
|
|
1997
|
+ class="z-99999 block rounded-sm border border-stroke bg-white p-1.5 shadow-sm dark:border-strokedark dark:bg-boxdark lg:hidden"
|
|
|
1998
|
+ @click.stop="sidebarToggle = !sidebarToggle">
|
|
|
1999
|
+ <span class="relative block h-5.5 w-5.5 cursor-pointer">
|
|
|
2000
|
+ <span class="du-block absolute right-0 h-full w-full">
|
|
|
2001
|
+ <span
|
|
|
2002
|
+ class="relative left-0 top-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-[0] duration-200 ease-in-out dark:bg-white"
|
|
|
2003
|
+ :class="{{ '!w-full delay-300': !sidebarToggle }}"
|
|
|
2004
|
+ ></span>
|
|
|
2005
|
+ <span
|
|
|
2006
|
+ class="relative left-0 top-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-150 duration-200 ease-in-out dark:bg-white"
|
|
|
2007
|
+ :class="{{ '!w-full delay-400': !sidebarToggle }}"
|
|
|
2008
|
+ ></span>
|
|
|
2009
|
+ <span
|
|
|
2010
|
+ class="relative left-0 top-0 my-1 block h-0.5 w-0 rounded-sm bg-black delay-200 duration-200 ease-in-out dark:bg-white"
|
|
|
2011
|
+ :class="{{ '!w-full delay-500': !sidebarToggle }}"
|
|
|
2012
|
+ ></span>
|
|
|
2013
|
+ </span>
|
|
|
2014
|
+ <span class="du-block absolute right-0 h-full w-full rotate-45">
|
|
|
2015
|
+ <span
|
|
|
2016
|
+ class="absolute left-2.5 top-0 block h-full w-0.5 rounded-sm bg-black delay-300 duration-200 ease-in-out dark:bg-white"
|
|
|
2017
|
+ :class="{{ '!h-0 delay-[0]': !sidebarToggle }}"
|
|
|
2018
|
+ ></span>
|
|
|
2019
|
+ <span
|
|
|
2020
|
+ class="delay-400 absolute left-0 top-2.5 block h-0.5 w-full rounded-sm bg-black duration-200 ease-in-out dark:bg-white"
|
|
|
2021
|
+ :class="{{ '!h-0 dealy-200': !sidebarToggle }}"
|
|
|
2022
|
+ ></span>
|
|
|
2023
|
+ </span>
|
|
|
2024
|
+ </span>
|
|
|
2025
|
+ </button>
|
|
|
2026
|
+ <!-- Hamburger Toggle BTN -->
|
|
|
2027
|
+ <a class="block flex-shrink-0 lg:hidden" href="index.html">
|
|
|
2028
|
+ <img src="https://demo.tailadmin.com/src/images/logo/logo-icon.svg" alt="Logo" />
|
|
|
2029
|
+ </a>
|
|
|
2030
|
+ </div>
|
|
|
2031
|
+
|
|
|
2032
|
+ <div class="hidden sm:block">
|
|
|
2033
|
+ <a href="#" class="inline-block text-2xl font-bold tracking-wider uppercase">{title}</a>
|
|
|
2034
|
+ </div>
|
|
1842
|
2035
|
|
|
1843
|
2036
|
<div class="flex items-center gap-3 2xsm:gap-7">
|
|
|
2037
|
+ <ul class="flex items-center gap-2 2xsm:gap-4">
|
|
|
2038
|
+ <li>
|
|
|
2039
|
+ <!-- Dark Mode Toggler -->
|
|
|
2040
|
+ <label
|
|
|
2041
|
+ :class="darkMode ? 'bg-primary' : 'bg-stroke'"
|
|
|
2042
|
+ class="relative m-0 block h-7.5 w-14 rounded-full"
|
|
|
2043
|
+ >
|
|
|
2044
|
+ <input
|
|
|
2045
|
+ type="checkbox"
|
|
|
2046
|
+ :value="darkMode"
|
|
|
2047
|
+ @change="darkMode = !darkMode"
|
|
|
2048
|
+ class="absolute top-0 z-50 m-0 h-full w-full cursor-pointer opacity-0"
|
|
|
2049
|
+ />
|
|
|
2050
|
+ <span
|
|
|
2051
|
+ :class="darkMode && '!right-1 !translate-x-full'"
|
|
|
2052
|
+ class="absolute left-1 top-1/2 flex h-6 w-6 -translate-y-1/2 translate-x-0 items-center justify-center rounded-full bg-white shadow-switcher duration-75 ease-linear"
|
|
|
2053
|
+ >
|
|
|
2054
|
+ <span class="dark:hidden">
|
|
|
2055
|
+ <svg
|
|
|
2056
|
+ width="16"
|
|
|
2057
|
+ height="16"
|
|
|
2058
|
+ viewBox="0 0 16 16"
|
|
|
2059
|
+ fill="none"
|
|
|
2060
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
2061
|
+ >
|
|
|
2062
|
+ <path
|
|
|
2063
|
+ d="M7.99992 12.6666C10.5772 12.6666 12.6666 10.5772 12.6666 7.99992C12.6666 5.42259 10.5772 3.33325 7.99992 3.33325C5.42259 3.33325 3.33325 5.42259 3.33325 7.99992C3.33325 10.5772 5.42259 12.6666 7.99992 12.6666Z"
|
|
|
2064
|
+ fill="#969AA1"
|
|
|
2065
|
+ />
|
|
|
2066
|
+ <path
|
|
|
2067
|
+ d="M8.00008 15.3067C7.63341 15.3067 7.33342 15.0334 7.33342 14.6667V14.6134C7.33342 14.2467 7.63341 13.9467 8.00008 13.9467C8.36675 13.9467 8.66675 14.2467 8.66675 14.6134C8.66675 14.9801 8.36675 15.3067 8.00008 15.3067ZM12.7601 13.4267C12.5867 13.4267 12.4201 13.3601 12.2867 13.2334L12.2001 13.1467C11.9401 12.8867 11.9401 12.4667 12.2001 12.2067C12.4601 11.9467 12.8801 11.9467 13.1401 12.2067L13.2267 12.2934C13.4867 12.5534 13.4867 12.9734 13.2267 13.2334C13.1001 13.3601 12.9334 13.4267 12.7601 13.4267ZM3.24008 13.4267C3.06675 13.4267 2.90008 13.3601 2.76675 13.2334C2.50675 12.9734 2.50675 12.5534 2.76675 12.2934L2.85342 12.2067C3.11342 11.9467 3.53341 11.9467 3.79341 12.2067C4.05341 12.4667 4.05341 12.8867 3.79341 13.1467L3.70675 13.2334C3.58008 13.3601 3.40675 13.4267 3.24008 13.4267ZM14.6667 8.66675H14.6134C14.2467 8.66675 13.9467 8.36675 13.9467 8.00008C13.9467 7.63341 14.2467 7.33342 14.6134 7.33342C14.9801 7.33342 15.3067 7.63341 15.3067 8.00008C15.3067 8.36675 15.0334 8.66675 14.6667 8.66675ZM1.38675 8.66675H1.33341C0.966748 8.66675 0.666748 8.36675 0.666748 8.00008C0.666748 7.63341 0.966748 7.33342 1.33341 7.33342C1.70008 7.33342 2.02675 7.63341 2.02675 8.00008C2.02675 8.36675 1.75341 8.66675 1.38675 8.66675ZM12.6734 3.99341C12.5001 3.99341 12.3334 3.92675 12.2001 3.80008C11.9401 3.54008 11.9401 3.12008 12.2001 2.86008L12.2867 2.77341C12.5467 2.51341 12.9667 2.51341 13.2267 2.77341C13.4867 3.03341 13.4867 3.45341 13.2267 3.71341L13.1401 3.80008C13.0134 3.92675 12.8467 3.99341 12.6734 3.99341ZM3.32675 3.99341C3.15341 3.99341 2.98675 3.92675 2.85342 3.80008L2.76675 3.70675C2.50675 3.44675 2.50675 3.02675 2.76675 2.76675C3.02675 2.50675 3.44675 2.50675 3.70675 2.76675L3.79341 2.85342C4.05341 3.11342 4.05341 3.53341 3.79341 3.79341C3.66675 3.92675 3.49341 3.99341 3.32675 3.99341ZM8.00008 2.02675C7.63341 2.02675 7.33342 1.75341 7.33342 1.38675V1.33341C7.33342 0.966748 7.63341 0.666748 8.00008 0.666748C8.36675 0.666748 8.66675 0.966748 8.66675 1.33341C8.66675 1.70008 8.36675 2.02675 8.00008 2.02675Z"
|
|
|
2068
|
+ fill="#969AA1"
|
|
|
2069
|
+ />
|
|
|
2070
|
+ </svg>
|
|
|
2071
|
+ </span>
|
|
|
2072
|
+ <span class="hidden dark:inline-block">
|
|
|
2073
|
+ <svg
|
|
|
2074
|
+ width="16"
|
|
|
2075
|
+ height="16"
|
|
|
2076
|
+ viewBox="0 0 16 16"
|
|
|
2077
|
+ fill="none"
|
|
|
2078
|
+ xmlns="http://www.w3.org/2000/svg"
|
|
|
2079
|
+ >
|
|
|
2080
|
+ <path
|
|
|
2081
|
+ d="M14.3533 10.62C14.2466 10.44 13.9466 10.16 13.1999 10.2933C12.7866 10.3667 12.3666 10.4 11.9466 10.38C10.3933 10.3133 8.98659 9.6 8.00659 8.5C7.13993 7.53333 6.60659 6.27333 6.59993 4.91333C6.59993 4.15333 6.74659 3.42 7.04659 2.72666C7.33993 2.05333 7.13326 1.7 6.98659 1.55333C6.83326 1.4 6.47326 1.18666 5.76659 1.48C3.03993 2.62666 1.35326 5.36 1.55326 8.28666C1.75326 11.04 3.68659 13.3933 6.24659 14.28C6.85993 14.4933 7.50659 14.62 8.17326 14.6467C8.27993 14.6533 8.38659 14.66 8.49326 14.66C10.7266 14.66 12.8199 13.6067 14.1399 11.8133C14.5866 11.1933 14.4666 10.8 14.3533 10.62Z"
|
|
|
2082
|
+ fill="#969AA1"
|
|
|
2083
|
+ />
|
|
|
2084
|
+ </svg>
|
|
|
2085
|
+ </span>
|
|
|
2086
|
+ </span>
|
|
|
2087
|
+ </label>
|
|
|
2088
|
+ <!-- Dark Mode Toggler -->
|
|
|
2089
|
+ </li>
|
|
|
2090
|
+ </ul>
|
|
|
2091
|
+
|
|
|
2092
|
+ <!-- User Area -->
|
|
1844
|
2093
|
<div class="relative" x-data="{{ dropdownOpen: false }}" @click.outside="dropdownOpen = false">
|
|
1845
|
2094
|
<a class="flex items-center gap-4" href="#" @click.prevent="dropdownOpen = ! dropdownOpen">
|
|
1846
|
2095
|
<span class="hidden text-right lg:block">
|
|
|
@@ -1897,7 +2146,9 @@ plot """
|
|
1897
|
2146
|
</div>
|
|
1898
|
2147
|
<!-- Dropdown End -->
|
|
1899
|
2148
|
</div>
|
|
1900
|
|
- </div>
|
|
|
2149
|
+ </div>
|
|
|
2150
|
+ <!-- User Area -->
|
|
|
2151
|
+
|
|
1901
|
2152
|
</div>
|
|
1902
|
2153
|
</header>'''
|
|
1903
|
2154
|
|
|
|
@@ -1915,7 +2166,6 @@ Please see the manual page for more details.
|
|
1915
|
2166
|
""" % conf
|
|
1916
|
2167
|
print(text)
|
|
1917
|
2168
|
|
|
1918
|
|
-
|
|
1919
|
2169
|
class GitStats:
|
|
1920
|
2170
|
def run(self, args_orig):
|
|
1921
|
2171
|
optlist, args = getopt.getopt(args_orig, 'hc:', ["help"])
|
|
|
@@ -1999,4 +2249,6 @@ if __name__=='__main__':
|
|
1999
|
2249
|
g.run(sys.argv[1:])
|
|
2000
|
2250
|
|
|
2001
|
2251
|
|
|
2002
|
|
-# https://github.com/TailAdmin/tailadmin-free-tailwind-dashboard-template/tree/main
|
|
|
2252
|
+# https://github.com/TailAdmin/tailadmin-free-tailwind-dashboard-template/tree/main
|
|
|
2253
|
+# https://codepen.io/Zsena/pen/ZEMaaoX?editors=1010
|
|
|
2254
|
+# https://sebastiandedeyne.com/non-reactive-data-in-alpine-js/
|