]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Refactor: loading component
authorshamoon <4887959+shamoon@users.noreply.github.com>
Fri, 6 Dec 2024 08:26:38 +0000 (00:26 -0800)
committershamoon <4887959+shamoon@users.noreply.github.com>
Fri, 6 Dec 2024 08:46:21 +0000 (00:46 -0800)
27 files changed:
src-ui/messages.xlf
src-ui/src/app/components/admin/config/config.component.ts
src-ui/src/app/components/admin/logs/logs.component.html
src-ui/src/app/components/admin/logs/logs.component.ts
src-ui/src/app/components/admin/tasks/tasks.component.ts
src-ui/src/app/components/admin/trash/trash.component.html
src-ui/src/app/components/admin/trash/trash.component.ts
src-ui/src/app/components/common/confirm-dialog/confirm-dialog.component.ts
src-ui/src/app/components/common/confirm-dialog/merge-confirm-dialog/merge-confirm-dialog.component.ts
src-ui/src/app/components/common/custom-field-display/custom-field-display.component.ts
src-ui/src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts
src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.ts
src-ui/src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/edit-dialog.component.ts
src-ui/src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts
src-ui/src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts
src-ui/src/app/components/common/profile-edit-dialog/profile-edit-dialog.component.ts
src-ui/src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.ts
src-ui/src/app/components/dashboard/widgets/widget-frame/widget-frame.component.ts
src-ui/src/app/components/loading-component/loading.component.spec.ts [new file with mode: 0644]
src-ui/src/app/components/loading-component/loading.component.ts [new file with mode: 0644]
src-ui/src/app/components/manage/custom-fields/custom-fields.component.spec.ts
src-ui/src/app/components/manage/custom-fields/custom-fields.component.ts
src-ui/src/app/components/manage/management-list/management-list.component.html
src-ui/src/app/components/manage/management-list/management-list.component.ts
src-ui/src/app/components/manage/saved-views/saved-views.component.ts
src-ui/src/app/components/manage/workflows/workflows.component.ts

index 999413c35cec9575175218c545d9e2e6ae8909a6..73b67b5b36ed4fb0db81d7c40d60014279c07c11 100644 (file)
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">127</context>
+          <context context-type="linenumber">124</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/dashboard/widgets/saved-view-widget/saved-view-widget.component.html</context>
         <source>Error retrieving config</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">81</context>
+          <context context-type="linenumber">76</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1172622527269118932" datatype="html">
         <source>Invalid JSON</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">107</context>
+          <context context-type="linenumber">102</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5103146006962696736" datatype="html">
         <source>Configuration updated</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">151</context>
+          <context context-type="linenumber">146</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1664963291286452273" datatype="html">
         <source>An error occurred updating configuration</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">156</context>
+          <context context-type="linenumber">151</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2653081282186526824" datatype="html">
         <source>File successfully updated</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">178</context>
+          <context context-type="linenumber">173</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5902783625859504265" datatype="html">
         <source>An error occurred uploading file</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/config/config.component.ts</context>
-          <context context-type="linenumber">183</context>
+          <context context-type="linenumber">178</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4804785061014590286" datatype="html">
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/confirm-dialog/confirm-dialog.component.ts</context>
-          <context context-type="linenumber">44</context>
+          <context context-type="linenumber">47</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/correspondent-edit-dialog/correspondent-edit-dialog.component.html</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">124</context>
+          <context context-type="linenumber">122</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2134950584701094962" datatype="html">
         <source>Dismiss selected</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">77</context>
+          <context context-type="linenumber">75</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8829078752502782653" datatype="html">
         <source>Dismiss all</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">78</context>
+          <context context-type="linenumber">76</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1323591410517879795" datatype="html">
         <source>Confirm Dismiss All</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">121</context>
+          <context context-type="linenumber">119</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4157200209636243740" datatype="html">
         <source>Dismiss all <x id="PH" equiv-text="tasks.size"/> tasks?</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">122</context>
+          <context context-type="linenumber">120</context>
         </context-group>
       </trans-unit>
       <trans-unit id="9011556615675272238" datatype="html">
         <source>queued</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">207</context>
+          <context context-type="linenumber">205</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6415892379431855826" datatype="html">
         <source>started</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">209</context>
+          <context context-type="linenumber">207</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7510279840486540181" datatype="html">
         <source>completed</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">211</context>
+          <context context-type="linenumber">209</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4083337005045748464" datatype="html">
         <source>failed</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/tasks/tasks.component.ts</context>
-          <context context-type="linenumber">213</context>
+          <context context-type="linenumber">211</context>
         </context-group>
       </trans-unit>
       <trans-unit id="3418677553313974490" datatype="html">
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">68</context>
+          <context context-type="linenumber">65</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">97</context>
+          <context context-type="linenumber">94</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.html</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">225</context>
+          <context context-type="linenumber">216</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.html</context>
         <source>Confirm delete</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">64</context>
+          <context context-type="linenumber">61</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">91</context>
+          <context context-type="linenumber">88</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">221</context>
+          <context context-type="linenumber">212</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">338</context>
+          <context context-type="linenumber">329</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1373208150912772963" datatype="html">
         <source>This operation will permanently delete this document.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">65</context>
+          <context context-type="linenumber">62</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5641451190833696892" datatype="html">
         <source>This operation cannot be undone.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">66</context>
+          <context context-type="linenumber">63</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">95</context>
+          <context context-type="linenumber">92</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/users-groups/users-groups.component.ts</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">93</context>
+          <context context-type="linenumber">89</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">340</context>
+          <context context-type="linenumber">331</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">124</context>
+          <context context-type="linenumber">119</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1980187861066369604" datatype="html">
         <source>Document deleted</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">75</context>
+          <context context-type="linenumber">72</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7295637485862454066" datatype="html">
         <source>Error deleting document</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">80</context>
+          <context context-type="linenumber">77</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/document-detail/document-detail.component.ts</context>
         <source>This operation will permanently delete the selected documents.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">93</context>
+          <context context-type="linenumber">90</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6804051092296228130" datatype="html">
         <source>This operation will permanently delete all documents in the trash.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">94</context>
+          <context context-type="linenumber">91</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6996183233986182894" datatype="html">
         <source>Document(s) deleted</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">105</context>
+          <context context-type="linenumber">102</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6962724852893361467" datatype="html">
         <source>Error deleting document(s)</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">112</context>
+          <context context-type="linenumber">109</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7534569062269274401" datatype="html">
         <source>Document restored</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">125</context>
+          <context context-type="linenumber">122</context>
         </context-group>
       </trans-unit>
       <trans-unit id="9136016619414048201" datatype="html">
         <source>Error restoring document</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">135</context>
+          <context context-type="linenumber">132</context>
         </context-group>
       </trans-unit>
       <trans-unit id="960063472770266304" datatype="html">
         <source>Document(s) restored</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">145</context>
+          <context context-type="linenumber">142</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8405416976953346141" datatype="html">
         <source>Error restoring document(s)</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/admin/trash/trash.component.ts</context>
-          <context context-type="linenumber">151</context>
+          <context context-type="linenumber">148</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8119815638230251386" datatype="html">
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">95</context>
+          <context context-type="linenumber">91</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/mail/mail.component.ts</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">342</context>
+          <context context-type="linenumber">333</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">126</context>
+          <context context-type="linenumber">121</context>
         </context-group>
       </trans-unit>
       <trans-unit id="857903183180440990" datatype="html">
         <source>Confirmation</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/confirm-dialog/confirm-dialog.component.ts</context>
-          <context context-type="linenumber">20</context>
+          <context context-type="linenumber">23</context>
         </context-group>
       </trans-unit>
       <trans-unit id="9178182467454450952" datatype="html">
         <source>Confirm</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/confirm-dialog/confirm-dialog.component.ts</context>
-          <context context-type="linenumber">32</context>
+          <context context-type="linenumber">35</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/permissions-dialog/permissions-dialog.component.html</context>
         <source>Saved field &quot;<x id="PH" equiv-text="newField.name"/>&quot;.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context>
-          <context context-type="linenumber">124</context>
+          <context context-type="linenumber">119</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">75</context>
+          <context context-type="linenumber">71</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1841172489943868696" datatype="html">
         <source>Error saving field.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/custom-fields-dropdown/custom-fields-dropdown.component.ts</context>
-          <context context-type="linenumber">133</context>
+          <context context-type="linenumber">128</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">83</context>
+          <context context-type="linenumber">79</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4465085913683915434" datatype="html">
         <source>Create new custom field</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts</context>
-          <context context-type="linenumber">87</context>
+          <context context-type="linenumber">79</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8751213029607178010" datatype="html">
         <source>Edit custom field</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component.ts</context>
-          <context context-type="linenumber">91</context>
+          <context context-type="linenumber">83</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6672809941092516947" datatype="html">
         <source>Create new item</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context>
-          <context context-type="linenumber">111</context>
+          <context context-type="linenumber">116</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5324147361912094446" datatype="html">
         <source>Edit item</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/edit-dialog.component.ts</context>
-          <context context-type="linenumber">115</context>
+          <context context-type="linenumber">120</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7878445132438733225" datatype="html">
         <source>Create new storage path</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts</context>
-          <context context-type="linenumber">63</context>
+          <context context-type="linenumber">56</context>
         </context-group>
       </trans-unit>
       <trans-unit id="3754859110054016570" datatype="html">
         <source>Edit storage path</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/edit-dialog/storage-path-edit-dialog/storage-path-edit-dialog.component.ts</context>
-          <context context-type="linenumber">67</context>
+          <context context-type="linenumber">60</context>
         </context-group>
       </trans-unit>
       <trans-unit id="9011959596901584887" datatype="html">
         <source>Not assigned</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
-          <context context-type="linenumber">370</context>
+          <context context-type="linenumber">373</context>
         </context-group>
         <note priority="1" from="description">Filter drop down element to filter for documents with no correspondent/type/tag assigned</note>
       </trans-unit>
         <source>Open <x id="PH" equiv-text="this.title"/> filter</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/common/filterable-dropdown/filterable-dropdown.component.ts</context>
-          <context context-type="linenumber">486</context>
+          <context context-type="linenumber">488</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7005745151564974365" datatype="html">
         <source>Confirm delete field</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">91</context>
+          <context context-type="linenumber">87</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2939457975223185057" datatype="html">
         <source>This operation will permanently delete this field.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">92</context>
+          <context context-type="linenumber">88</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5137089475515834162" datatype="html">
         <source>Deleted field</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">101</context>
+          <context context-type="linenumber">97</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6352403551920829405" datatype="html">
         <source>Error deleting field.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/custom-fields/custom-fields.component.ts</context>
-          <context context-type="linenumber">107</context>
+          <context context-type="linenumber">103</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8084492669582894778" datatype="html">
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">325</context>
+          <context context-type="linenumber">316</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4010735610815226758" datatype="html">
         <source>Automatic</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">125</context>
+          <context context-type="linenumber">116</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/data/matching-model.ts</context>
         <source>None</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">127</context>
+          <context context-type="linenumber">118</context>
         </context-group>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/data/matching-model.ts</context>
         <source>Successfully created <x id="PH" equiv-text="this.typeName"/>.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">178</context>
+          <context context-type="linenumber">169</context>
         </context-group>
       </trans-unit>
       <trans-unit id="3928835053823658072" datatype="html">
         <source>Error occurred while creating <x id="PH" equiv-text="this.typeName"/>.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">183</context>
+          <context context-type="linenumber">174</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2541368547549828690" datatype="html">
         <source>Successfully updated <x id="PH" equiv-text="this.typeName"/>.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">198</context>
+          <context context-type="linenumber">189</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6442673774206210733" datatype="html">
         <source>Error occurred while saving <x id="PH" equiv-text="this.typeName"/>.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">203</context>
+          <context context-type="linenumber">194</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8371896857609524947" datatype="html">
         <source>Associated documents will not be deleted.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">223</context>
+          <context context-type="linenumber">214</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6639207128255974941" datatype="html">
         <source>Error while deleting element</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">239</context>
+          <context context-type="linenumber">230</context>
         </context-group>
       </trans-unit>
       <trans-unit id="4863024195229581844" datatype="html">
         <source>Permissions updated successfully</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">318</context>
+          <context context-type="linenumber">309</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1464476612812630086" datatype="html">
         <source>This operation will permanently delete all objects.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">339</context>
+          <context context-type="linenumber">330</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5897787932098828336" datatype="html">
         <source>Objects deleted successfully</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">353</context>
+          <context context-type="linenumber">344</context>
         </context-group>
       </trans-unit>
       <trans-unit id="8273353839648035634" datatype="html">
         <source>Error deleting objects</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/management-list/management-list.component.ts</context>
-          <context context-type="linenumber">359</context>
+          <context context-type="linenumber">350</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1930477323485553035" datatype="html">
         <source>Saved view &quot;<x id="PH" equiv-text="savedView.name"/>&quot; deleted.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.ts</context>
-          <context context-type="linenumber">113</context>
+          <context context-type="linenumber">110</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1660419335376265526" datatype="html">
         <source>Views saved successfully.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.ts</context>
-          <context context-type="linenumber">138</context>
+          <context context-type="linenumber">135</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1699877326523238632" datatype="html">
         <source>Error while saving views.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/saved-views/saved-views.component.ts</context>
-          <context context-type="linenumber">143</context>
+          <context context-type="linenumber">140</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5101757640976222639" datatype="html">
         <source>Saved workflow &quot;<x id="PH" equiv-text="newWorkflow.name"/>&quot;.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">87</context>
+          <context context-type="linenumber">82</context>
         </context-group>
       </trans-unit>
       <trans-unit id="7593065565369163325" datatype="html">
         <source>Error saving workflow.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">95</context>
+          <context context-type="linenumber">90</context>
         </context-group>
       </trans-unit>
       <trans-unit id="563460864902055482" datatype="html">
         <source>Confirm delete workflow</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">122</context>
+          <context context-type="linenumber">117</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6874008462443189248" datatype="html">
         <source>This operation will permanently delete this workflow.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">123</context>
+          <context context-type="linenumber">118</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1848226135059921165" datatype="html">
         <source>Deleted workflow</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">132</context>
+          <context context-type="linenumber">127</context>
         </context-group>
       </trans-unit>
       <trans-unit id="3177411222429626224" datatype="html">
         <source>Error deleting workflow.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">137</context>
+          <context context-type="linenumber">132</context>
         </context-group>
       </trans-unit>
       <trans-unit id="5459159218551862653" datatype="html">
         <source>Enabled workflow</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">148</context>
+          <context context-type="linenumber">143</context>
         </context-group>
       </trans-unit>
       <trans-unit id="6035681056091592756" datatype="html">
         <source>Disabled workflow</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">149</context>
+          <context context-type="linenumber">144</context>
         </context-group>
       </trans-unit>
       <trans-unit id="1376040678213338380" datatype="html">
         <source>Error toggling workflow.</source>
         <context-group purpose="location">
           <context context-type="sourcefile">src/app/components/manage/workflows/workflows.component.ts</context>
-          <context context-type="linenumber">155</context>
+          <context context-type="linenumber">150</context>
         </context-group>
       </trans-unit>
       <trans-unit id="2649252321173430744" datatype="html">
index 63e66d456a0bcc5c8398c808789a0f35e3361804..acc644412d2be6b36d227e671f3bf56348410541 100644 (file)
@@ -17,9 +17,9 @@ import {
 } from 'src/app/data/paperless-config'
 import { ConfigService } from 'src/app/services/config.service'
 import { ToastService } from 'src/app/services/toast.service'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
 import { DirtyComponent, dirtyCheck } from '@ngneat/dirty-check-forms'
 import { SettingsService } from 'src/app/services/settings.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-config',
@@ -27,7 +27,7 @@ import { SettingsService } from 'src/app/services/settings.service'
   styleUrl: './config.component.scss',
 })
 export class ConfigComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit, OnDestroy, DirtyComponent
 {
   public readonly ConfigOptionType = ConfigOptionType
@@ -45,15 +45,11 @@ export class ConfigComponent
     return PaperlessConfigOptions.filter((o) => o.category === category)
   }
 
-  public loading: boolean = false
-
   initialConfig: PaperlessConfig
   store: BehaviorSubject<any>
   storeSub: Subscription
   isDirty$: Observable<boolean>
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   constructor(
     private configService: ConfigService,
     private toastService: ToastService,
@@ -67,7 +63,6 @@ export class ConfigComponent
   }
 
   ngOnInit(): void {
-    this.loading = true
     this.configService
       .getConfig()
       .pipe(takeUntil(this.unsubscribeNotifier))
index 7d2c5f092a7b7fcc7024edf2bdd0329ad8e35ea9..efdba66d0c157f0deaf4ada3df4284a0e2df4d66 100644 (file)
@@ -17,7 +17,7 @@
       </a>
     </li>
   }
-  @if (isLoading || !logFiles.length) {
+  @if (loading || !logFiles.length) {
     <div class="ps-2 d-flex align-items-center">
       <div class="spinner-border spinner-border-sm me-2" role="status"></div>
       @if (!logFiles.length) {
@@ -30,7 +30,7 @@
 <div [ngbNavOutlet]="nav" class="mt-2"></div>
 
 <div class="bg-dark p-3 text-light font-monospace log-container" #logContainer>
-  @if (isLoading && logFiles.length) {
+  @if (loading && logFiles.length) {
     <div>
       <div class="spinner-border spinner-border-sm me-2" role="status"></div>
       <ng-container i18n>Loading...</ng-container>
index 1b2dbef3e8c39dc6517ffd242a4f91fbee562772..508f7b3b71e588c54747e3cc4d91a2a8cb8c01ae 100644 (file)
@@ -3,22 +3,28 @@ import {
   ElementRef,
   OnInit,
   ViewChild,
-  OnDestroy,
   ChangeDetectorRef,
+  OnDestroy,
 } from '@angular/core'
-import { Subject, takeUntil } from 'rxjs'
+import { takeUntil } from 'rxjs'
 import { LogService } from 'src/app/services/rest/log.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-logs',
   templateUrl: './logs.component.html',
   styleUrls: ['./logs.component.scss'],
 })
-export class LogsComponent implements OnInit, OnDestroy {
+export class LogsComponent
+  extends LoadingComponentWithPermissions
+  implements OnInit, OnDestroy
+{
   constructor(
     private logService: LogService,
     private changedetectorRef: ChangeDetectorRef
-  ) {}
+  ) {
+    super()
+  }
 
   public logs: string[] = []
 
@@ -26,22 +32,17 @@ export class LogsComponent implements OnInit, OnDestroy {
 
   public activeLog: string
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
-  public isLoading: boolean = false
-
   public autoRefreshInterval: any
 
   @ViewChild('logContainer') logContainer: ElementRef
 
   ngOnInit(): void {
-    this.isLoading = true
     this.logService
       .list()
       .pipe(takeUntil(this.unsubscribeNotifier))
       .subscribe((result) => {
         this.logFiles = result
-        this.isLoading = false
+        this.loading = false
         if (this.logFiles.length > 0) {
           this.activeLog = this.logFiles[0]
           this.reloadLogs()
@@ -51,25 +52,24 @@ export class LogsComponent implements OnInit, OnDestroy {
   }
 
   ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
+    super.ngOnDestroy()
     clearInterval(this.autoRefreshInterval)
   }
 
   reloadLogs() {
-    this.isLoading = true
+    this.loading = true
     this.logService
       .get(this.activeLog)
       .pipe(takeUntil(this.unsubscribeNotifier))
       .subscribe({
         next: (result) => {
           this.logs = result
-          this.isLoading = false
+          this.loading = false
           this.scrollToBottom()
         },
         error: () => {
           this.logs = []
-          this.isLoading = false
+          this.loading = false
         },
       })
   }
index 6539b3692629240eedab0d76def43f204b3599dd..f88490a05ed75a3d771848efddfae3beac64176d 100644 (file)
@@ -12,7 +12,7 @@ import {
 import { PaperlessTask } from 'src/app/data/paperless-task'
 import { TasksService } from 'src/app/services/tasks.service'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 export enum TaskTab {
   Queued = 'queued',
@@ -37,7 +37,7 @@ const FILTER_TARGETS = [
   styleUrls: ['./tasks.component.scss'],
 })
 export class TasksComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit, OnDestroy
 {
   public activeTab: TaskTab
@@ -70,8 +70,6 @@ export class TasksComponent
       : FILTER_TARGETS.slice(0, 1)
   }
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   get dismissButtonText(): string {
     return this.selectedTasks.size > 0
       ? $localize`Dismiss selected`
@@ -101,9 +99,9 @@ export class TasksComponent
   }
 
   ngOnDestroy() {
+    super.ngOnDestroy()
     this.tasksService.cancelPending()
     clearInterval(this.autoRefreshInterval)
-    this.unsubscribeNotifier.next(this)
   }
 
   dismissTask(task: PaperlessTask) {
index a148f203391301bb45c63d3df5d7cd65356bef82..d03d8d98e659ebec8611adbfabac38aa8bb216bb 100644 (file)
@@ -38,7 +38,7 @@
             </tr>
         </thead>
         <tbody>
-            @if (isLoading) {
+            @if (loading) {
                 <tr>
                     <td colspan="5">
                     <div class="spinner-border spinner-border-sm me-2" role="status"></div>
@@ -88,7 +88,7 @@
     </table>
 </div>
 
-@if (!isLoading) {
+@if (!loading) {
     <div class="d-flex mb-2">
         <div>
             <ng-container i18n>{totalDocuments, plural, =1 {One document in trash} other {{{totalDocuments || 0}} total documents in trash}}</ng-container>
index 055c5fa97bda7db761c503162f2580d6b9c2593e..5f312cc505f18c90d2bfbb4c93f2fae6ef4159df 100644 (file)
@@ -4,25 +4,26 @@ import { Document } from 'src/app/data/document'
 import { ToastService } from 'src/app/services/toast.service'
 import { TrashService } from 'src/app/services/trash.service'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
-import { delay, Subject, takeUntil, tap } from 'rxjs'
+import { delay, takeUntil, tap } from 'rxjs'
 import { SettingsService } from 'src/app/services/settings.service'
 import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
 import { Router } from '@angular/router'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-trash',
   templateUrl: './trash.component.html',
   styleUrl: './trash.component.scss',
 })
-export class TrashComponent implements OnDestroy {
+export class TrashComponent
+  extends LoadingComponentWithPermissions
+  implements OnDestroy
+{
   public documentsInTrash: Document[] = []
   public selectedDocuments: Set<number> = new Set()
   public allToggled: boolean = false
   public page: number = 1
   public totalDocuments: number
-  public isLoading: boolean = false
-  public reveal: boolean = false
-  unsubscribeNotifier: Subject<void> = new Subject()
 
   constructor(
     private trashService: TrashService,
@@ -31,16 +32,12 @@ export class TrashComponent implements OnDestroy {
     private settingsService: SettingsService,
     private router: Router
   ) {
+    super()
     this.reload()
   }
 
-  ngOnDestroy() {
-    this.unsubscribeNotifier.next()
-    this.unsubscribeNotifier.complete()
-  }
-
   reload() {
-    this.isLoading = true
+    this.loading = true
     this.trashService
       .getTrash(this.page)
       .pipe(
@@ -48,12 +45,12 @@ export class TrashComponent implements OnDestroy {
           this.documentsInTrash = r.results
           this.totalDocuments = r.count
           this.selectedDocuments.clear()
+          this.loading = false
         }),
         delay(100)
       )
       .subscribe(() => {
         this.reveal = true
-        this.isLoading = false
       })
   }
 
index 2dfb6a15d29a0b56817c8c17a1a87972869eabd1..f854f4adacb63b6aee1e3d0c7330cfaad9000590 100644 (file)
@@ -1,14 +1,17 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { interval, Subject, take } from 'rxjs'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-confirm-dialog',
   templateUrl: './confirm-dialog.component.html',
   styleUrls: ['./confirm-dialog.component.scss'],
 })
-export class ConfirmDialogComponent {
-  constructor(public activeModal: NgbActiveModal) {}
+export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
+  constructor(public activeModal: NgbActiveModal) {
+    super()
+  }
 
   @Output()
   public confirmClicked = new EventEmitter()
index 1530620e18d6faed3280c8f05c48101ebc7232f8..a8f88b9433119f3ae954946fe7bd14b248bd5f3f 100644 (file)
@@ -25,8 +25,6 @@ export class MergeConfirmDialogComponent
 
   public metadataDocumentID: number = -1
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   constructor(
     activeModal: NgbActiveModal,
     private documentService: DocumentService,
index 1ab831f4610f9e8f4c4862d172b15c8820e390f2..c4f05ae7f87029ca8639cb0729ab48d26179906a 100644 (file)
@@ -1,25 +1,22 @@
 import { getLocaleCurrencyCode } from '@angular/common'
-import {
-  Component,
-  Inject,
-  Input,
-  LOCALE_ID,
-  OnDestroy,
-  OnInit,
-} from '@angular/core'
-import { Subject, takeUntil } from 'rxjs'
+import { Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'
+import { takeUntil } from 'rxjs'
 import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
 import { DisplayField, Document } from 'src/app/data/document'
 import { Results } from 'src/app/data/results'
 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
 import { DocumentService } from 'src/app/services/rest/document.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-custom-field-display',
   templateUrl: './custom-field-display.component.html',
   styleUrl: './custom-field-display.component.scss',
 })
-export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
+export class CustomFieldDisplayComponent
+  extends LoadingComponentWithPermissions
+  implements OnInit
+{
   CustomFieldDataType = CustomFieldDataType
 
   private _document: Document
@@ -61,7 +58,6 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
 
   private docLinkDocuments: Document[] = []
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
   private defaultCurrencyCode: any
 
   constructor(
@@ -69,6 +65,7 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
     private documentService: DocumentService,
     @Inject(LOCALE_ID) currentLocale: string
   ) {
+    super()
     this.defaultCurrencyCode = getLocaleCurrencyCode(currentLocale)
     this.customFieldService.listAll().subscribe((r) => {
       this.customFields = r.results
@@ -120,9 +117,4 @@ export class CustomFieldDisplayComponent implements OnInit, OnDestroy {
   public getSelectValue(field: CustomField, id: string): string {
     return field.extra_data.select_options?.find((o) => o.id === id)?.label
   }
-
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
-  }
 }
index 652d7f3d8db56fe62108ac03d57c1df651aff7a9..f8732c4f8b2060178e108eaeb5c9df294f534143 100644 (file)
@@ -10,7 +10,7 @@ import {
   ViewChildren,
 } from '@angular/core'
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
-import { Subject, first, takeUntil } from 'rxjs'
+import { first, takeUntil } from 'rxjs'
 import { CustomField, DATA_TYPE_LABELS } from 'src/app/data/custom-field'
 import { CustomFieldInstance } from 'src/app/data/custom-field-instance'
 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
@@ -21,13 +21,14 @@ import {
   PermissionType,
   PermissionsService,
 } from 'src/app/services/permissions.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-custom-fields-dropdown',
   templateUrl: './custom-fields-dropdown.component.html',
   styleUrls: ['./custom-fields-dropdown.component.scss'],
 })
-export class CustomFieldsDropdownComponent implements OnDestroy {
+export class CustomFieldsDropdownComponent extends LoadingComponentWithPermissions {
   @Input()
   documentId: number
 
@@ -60,8 +61,6 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
 
   public filterText: string
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   get canCreateFields(): boolean {
     return this.permissionsService.currentUserCan(
       PermissionAction.Add,
@@ -75,14 +74,10 @@ export class CustomFieldsDropdownComponent implements OnDestroy {
     private toastService: ToastService,
     private permissionsService: PermissionsService
   ) {
+    super()
     this.getFields()
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(this)
-    this.unsubscribeNotifier.complete()
-  }
-
   private getFields() {
     this.customFieldsService
       .listAll()
index 2233fc5c48eb952ff9501f160b30325acd2e923f..e10eb69722deee987627bebdac7f3e539483e1d3 100644 (file)
@@ -2,7 +2,6 @@ import {
   Component,
   EventEmitter,
   Input,
-  OnDestroy,
   Output,
   QueryList,
   ViewChild,
@@ -29,6 +28,7 @@ import {
   CustomFieldQueryAtom,
 } from 'src/app/utils/custom-field-query-element'
 import { popperOptionsReenablePreventOverflow } from 'src/app/utils/popper-options'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 export class CustomFieldQueriesModel {
   public queries: CustomFieldQueryElement[] = []
@@ -157,7 +157,7 @@ export class CustomFieldQueriesModel {
   templateUrl: './custom-fields-query-dropdown.component.html',
   styleUrls: ['./custom-fields-query-dropdown.component.scss'],
 })
-export class CustomFieldsQueryDropdownComponent implements OnDestroy {
+export class CustomFieldsQueryDropdownComponent extends LoadingComponentWithPermissions {
   public CustomFieldQueryComponentType = CustomFieldQueryElementType
   public CustomFieldQueryOperator = CustomFieldQueryOperator
   public CustomFieldDataType = CustomFieldDataType
@@ -223,19 +223,13 @@ export class CustomFieldsQueryDropdownComponent implements OnDestroy {
 
   customFields: CustomField[] = []
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   constructor(protected customFieldsService: CustomFieldsService) {
+    super()
     this.selectionModel = new CustomFieldQueriesModel()
     this.getFields()
     this.reset()
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(this)
-    this.unsubscribeNotifier.complete()
-  }
-
   public onOpenChange(open: boolean) {
     if (open) {
       if (this.selectionModel.queries.length === 0) {
index e39e27edda57af74fd5d086d1c83fcedb1a81c02..a3392290e4fb0d2ecd90998e7001016646514bf1 100644 (file)
@@ -2,7 +2,6 @@ import {
   AfterViewInit,
   Component,
   ElementRef,
-  OnDestroy,
   OnInit,
   QueryList,
   ViewChildren,
@@ -18,7 +17,7 @@ import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service
 import { UserService } from 'src/app/services/rest/user.service'
 import { SettingsService } from 'src/app/services/settings.service'
 import { EditDialogComponent, EditDialogMode } from '../edit-dialog.component'
-import { Subject, takeUntil } from 'rxjs'
+import { takeUntil } from 'rxjs'
 
 @Component({
   selector: 'pngx-custom-field-edit-dialog',
@@ -27,15 +26,13 @@ import { Subject, takeUntil } from 'rxjs'
 })
 export class CustomFieldEditDialogComponent
   extends EditDialogComponent<CustomField>
-  implements OnInit, AfterViewInit, OnDestroy
+  implements OnInit, AfterViewInit
 {
   CustomFieldDataType = CustomFieldDataType
 
   @ViewChildren('selectOption')
   private selectOptionInputs: QueryList<ElementRef>
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   private get selectOptions(): FormArray {
     return (this.objectForm.controls.extra_data as FormGroup).controls
       .select_options as FormArray
@@ -78,11 +75,6 @@ export class CustomFieldEditDialogComponent
       })
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
-  }
-
   getCreateTitle() {
     return $localize`Create new custom field`
   }
index fe4d0bf019842d735769e4fe7c34bf30847952ef..ba32549f36627dc53fc6fc0e996e16a36832e010 100644 (file)
@@ -15,6 +15,7 @@ import { UserService } from 'src/app/services/rest/user.service'
 import { PermissionsFormObject } from '../input/permissions/permissions-form/permissions-form.component'
 import { SettingsService } from 'src/app/services/settings.service'
 import { SETTINGS_KEYS } from 'src/app/data/ui-settings'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 export enum EditDialogMode {
   CREATE = 0,
@@ -23,15 +24,19 @@ export enum EditDialogMode {
 
 @Directive()
 export abstract class EditDialogComponent<
-  T extends ObjectWithPermissions | ObjectWithId,
-> implements OnInit
+    T extends ObjectWithPermissions | ObjectWithId,
+  >
+  extends LoadingComponentWithPermissions
+  implements OnInit
 {
   constructor(
     protected service: AbstractPaperlessService<T>,
     private activeModal: NgbActiveModal,
     private userService: UserService,
     private settingsService: SettingsService
-  ) {}
+  ) {
+    super()
+  }
 
   users: User[]
 
index 214f08f117d22931b41612ec744cf18c7760d038..ae7a047bf2ad36c4d613fe772b937e131b56d497 100644 (file)
@@ -41,8 +41,6 @@ export class StoragePathEditDialogComponent
   public loading = false
   public testLoading = false
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   constructor(
     service: StoragePathService,
     activeModal: NgbActiveModal,
@@ -54,11 +52,6 @@ export class StoragePathEditDialogComponent
     this.initPathObservables()
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(this)
-    this.unsubscribeNotifier.complete()
-  }
-
   getCreateTitle() {
     return $localize`Create new storage path`
   }
index 2351dc0dade0686390d6e649c054292232c68ece..925e4f3191ac61909a1e019d442759cdad21f593 100644 (file)
@@ -6,7 +6,6 @@ import {
   ElementRef,
   ViewChild,
   OnInit,
-  OnDestroy,
 } from '@angular/core'
 import { FilterPipe } from 'src/app/pipes/filter.pipe'
 import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'
@@ -17,6 +16,7 @@ import { SelectionDataItem } from 'src/app/services/rest/document.service'
 import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
 import { HotKeyService } from 'src/app/services/hot-key.service'
 import { popperOptionsReenablePreventOverflow } from 'src/app/utils/popper-options'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 export interface ChangedItems {
   itemsToAdd: MatchingModel[]
@@ -353,7 +353,10 @@ export class FilterableDropdownSelectionModel {
   templateUrl: './filterable-dropdown.component.html',
   styleUrls: ['./filterable-dropdown.component.scss'],
 })
-export class FilterableDropdownComponent implements OnDestroy, OnInit {
+export class FilterableDropdownComponent
+  extends LoadingComponentWithPermissions
+  implements OnInit
+{
   @ViewChild('listFilterTextInput') listFilterTextInput: ElementRef
   @ViewChild('dropdown') dropdown: NgbDropdown
   @ViewChild('buttonItems') buttonItems: ElementRef
@@ -467,12 +470,11 @@ export class FilterableDropdownComponent implements OnDestroy, OnInit {
 
   private keyboardIndex: number
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
   constructor(
     private filterPipe: FilterPipe,
     private hotkeyService: HotKeyService
   ) {
+    super()
     this.selectionModelChange.subscribe((updatedModel) => {
       this.modelIsDirty = updatedModel.isDirty()
     })
@@ -495,11 +497,6 @@ export class FilterableDropdownComponent implements OnDestroy, OnInit {
     }
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
-  }
-
   applyClicked() {
     if (this.selectionModel.isDirty()) {
       this.dropdown.close()
index a4dbaf7d6ef0d76e4d010571c1b41852981b29f8..4256bfdd7bf5ad7d08d68d5e9f486c523f7d2dfa 100644 (file)
@@ -1,4 +1,4 @@
-import { Component, OnDestroy, OnInit } from '@angular/core'
+import { Component, OnInit } from '@angular/core'
 import { FormControl, FormGroup } from '@angular/forms'
 import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
 import { ProfileService } from 'src/app/services/profile.service'
@@ -8,18 +8,21 @@ import {
   SocialAccountProvider,
 } from 'src/app/data/user-profile'
 import { ToastService } from 'src/app/services/toast.service'
-import { Subject, takeUntil } from 'rxjs'
+import { takeUntil } from 'rxjs'
 import { Clipboard } from '@angular/cdk/clipboard'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-profile-edit-dialog',
   templateUrl: './profile-edit-dialog.component.html',
   styleUrls: ['./profile-edit-dialog.component.scss'],
 })
-export class ProfileEditDialogComponent implements OnInit, OnDestroy {
+export class ProfileEditDialogComponent
+  extends LoadingComponentWithPermissions
+  implements OnInit
+{
   public networkActive: boolean = false
   public error: any
-  private unsubscribeNotifier: Subject<any> = new Subject()
 
   public form = new FormGroup({
     email: new FormControl(''),
@@ -60,7 +63,9 @@ export class ProfileEditDialogComponent implements OnInit, OnDestroy {
     public activeModal: NgbActiveModal,
     private toastService: ToastService,
     private clipboard: Clipboard
-  ) {}
+  ) {
+    super()
+  }
 
   ngOnInit(): void {
     this.networkActive = true
@@ -93,11 +98,6 @@ export class ProfileEditDialogComponent implements OnInit, OnDestroy {
       })
   }
 
-  ngOnDestroy(): void {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
-  }
-
   get saveDisabled(): boolean {
     return this.error?.password_confirm || this.error?.email_confirm
   }
index 74c3af5200265df44f0825d4d0a9088b8e86be5d..fccf007b590fcb55c2a074d7c3e3ab3b5d99f770 100644 (file)
@@ -28,7 +28,6 @@ import {
 } from 'src/app/data/filter-rule-type'
 import { OpenDocumentsService } from 'src/app/services/open-documents.service'
 import { DocumentListViewService } from 'src/app/services/document-list-view.service'
-import { ComponentWithPermissions } from 'src/app/components/with-permissions/with-permissions.component'
 import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
 import {
   PermissionAction,
@@ -38,6 +37,7 @@ import {
 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
 import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field'
 import { SettingsService } from 'src/app/services/settings.service'
+import { LoadingComponentWithPermissions } from 'src/app/components/loading-component/loading.component'
 
 @Component({
   selector: 'pngx-saved-view-widget',
@@ -45,16 +45,13 @@ import { SettingsService } from 'src/app/services/settings.service'
   styleUrls: ['./saved-view-widget.component.scss'],
 })
 export class SavedViewWidgetComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit, OnDestroy
 {
   public DisplayMode = DisplayMode
   public DisplayField = DisplayField
   public CustomFieldDataType = CustomFieldDataType
 
-  public loading: boolean = true
-  public reveal: boolean = false
-
   private customFields: CustomField[] = []
 
   constructor(
index 2a141be7c9ed7e271d548dd30c4e42079e125b43..0ebe3b5ea4bec86d1977b0a691ae39d2a69bf6aa 100644 (file)
@@ -1,12 +1,18 @@
 import { AfterViewInit, Component, Input } from '@angular/core'
+import { LoadingComponentWithPermissions } from 'src/app/components/loading-component/loading.component'
 
 @Component({
   selector: 'pngx-widget-frame',
   templateUrl: './widget-frame.component.html',
   styleUrls: ['./widget-frame.component.scss'],
 })
-export class WidgetFrameComponent implements AfterViewInit {
-  constructor() {}
+export class WidgetFrameComponent
+  extends LoadingComponentWithPermissions
+  implements AfterViewInit
+{
+  constructor() {
+    super()
+  }
 
   @Input()
   title: string
@@ -17,8 +23,6 @@ export class WidgetFrameComponent implements AfterViewInit {
   @Input()
   draggable: any
 
-  public reveal: boolean = false
-
   ngAfterViewInit(): void {
     setTimeout(() => {
       this.reveal = true
diff --git a/src-ui/src/app/components/loading-component/loading.component.spec.ts b/src-ui/src/app/components/loading-component/loading.component.spec.ts
new file mode 100644 (file)
index 0000000..091745c
--- /dev/null
@@ -0,0 +1,43 @@
+import { TestBed } from '@angular/core/testing'
+import { Subject } from 'rxjs'
+import { LoadingComponentWithPermissions } from './loading.component'
+import { ComponentWithPermissions } from '../with-permissions/with-permissions.component'
+import { Component } from '@angular/core'
+
+class MockComponentWithPermissions extends ComponentWithPermissions {}
+
+@Component({
+  template: '',
+})
+class MockLoadingComponent extends LoadingComponentWithPermissions {}
+
+describe('LoadingComponentWithPermissions', () => {
+  let component: LoadingComponentWithPermissions
+
+  beforeEach(async () => {
+    TestBed.configureTestingModule({
+      declarations: [LoadingComponentWithPermissions],
+    })
+    component = new MockLoadingComponent()
+  })
+
+  it('should create', () => {
+    expect(component).toBeTruthy()
+  })
+
+  it('should have loading set to true by default', () => {
+    expect(component.loading).toBeTruthy()
+  })
+
+  it('should have reveal set to false by default', () => {
+    expect(component.reveal).toBeFalsy()
+  })
+
+  it('should call next and complete on unsubscribeNotifier with itself on destroy', () => {
+    const nextSpy = jest.spyOn(component['unsubscribeNotifier'], 'next')
+    const completeSpy = jest.spyOn(component['unsubscribeNotifier'], 'complete')
+    component.ngOnDestroy()
+    expect(nextSpy).toHaveBeenCalledWith(component)
+    expect(completeSpy).toHaveBeenCalled()
+  })
+})
diff --git a/src-ui/src/app/components/loading-component/loading.component.ts b/src-ui/src/app/components/loading-component/loading.component.ts
new file mode 100644 (file)
index 0000000..dcd8340
--- /dev/null
@@ -0,0 +1,23 @@
+import { Subject } from 'rxjs'
+import { ComponentWithPermissions } from '../with-permissions/with-permissions.component'
+import { Directive, OnDestroy } from '@angular/core'
+
+@Directive()
+export abstract class LoadingComponentWithPermissions
+  extends ComponentWithPermissions
+  implements OnDestroy
+{
+  public loading: boolean = true
+  public reveal: boolean = false
+
+  protected unsubscribeNotifier: Subject<any> = new Subject()
+
+  constructor() {
+    super()
+  }
+
+  ngOnDestroy(): void {
+    this.unsubscribeNotifier.next(this)
+    this.unsubscribeNotifier.complete()
+  }
+}
index 1be5484c11e07b7d946a365a4b7e123d6b02b4eb..c927b52dae910fff5b79462ebbc7c6dea056d67b 100644 (file)
@@ -28,6 +28,7 @@ import {
   CustomFieldQueryLogicalOperator,
   CustomFieldQueryOperator,
 } from 'src/app/data/custom-field-query'
+import { SettingsService } from 'src/app/services/settings.service'
 
 const fields: CustomField[] = [
   {
@@ -49,6 +50,7 @@ describe('CustomFieldsComponent', () => {
   let modalService: NgbModal
   let toastService: ToastService
   let listViewService: DocumentListViewService
+  let settingsService: SettingsService
 
   beforeEach(() => {
     TestBed.configureTestingModule({
@@ -91,6 +93,8 @@ describe('CustomFieldsComponent', () => {
     modalService = TestBed.inject(NgbModal)
     toastService = TestBed.inject(ToastService)
     listViewService = TestBed.inject(DocumentListViewService)
+    settingsService = TestBed.inject(SettingsService)
+    settingsService.currentUser = { id: 0, username: 'test' }
 
     fixture = TestBed.createComponent(CustomFieldsComponent)
     component = fixture.componentInstance
index 9300a0c2c7b28ffe737787545f2ba29e1f87e7c4..7bf4066b9d0bb43021192cb7f75c1687ba02a903 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, OnInit } from '@angular/core'
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
-import { delay, Subject, takeUntil, tap } from 'rxjs'
+import { delay, takeUntil, tap } from 'rxjs'
 import { DATA_TYPE_LABELS, CustomField } from 'src/app/data/custom-field'
 import { PermissionsService } from 'src/app/services/permissions.service'
 import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service'
@@ -8,7 +8,6 @@ import { ToastService } from 'src/app/services/toast.service'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
 import { CustomFieldEditDialogComponent } from '../../common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component'
 import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
 import { DocumentListViewService } from 'src/app/services/document-list-view.service'
 import { FILTER_CUSTOM_FIELDS_QUERY } from 'src/app/data/filter-rule-type'
 import {
@@ -16,6 +15,7 @@ import {
   CustomFieldQueryOperator,
 } from 'src/app/data/custom-field-query'
 import { SettingsService } from 'src/app/services/settings.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-custom-fields',
@@ -23,15 +23,11 @@ import { SettingsService } from 'src/app/services/settings.service'
   styleUrls: ['./custom-fields.component.scss'],
 })
 export class CustomFieldsComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit
 {
   public fields: CustomField[] = []
 
-  public loading: boolean = true
-  public reveal: boolean = false
-
-  private unsubscribeNotifier: Subject<any> = new Subject()
   constructor(
     private customFieldsService: CustomFieldsService,
     public permissionsService: PermissionsService,
index 6dbe590c76767eef42746fa937b3403d117b0657..7d464749112d1e54368364342a4670085773f757 100644 (file)
@@ -44,7 +44,7 @@
       </tr>
     </thead>
     <tbody>
-      @if (isLoading) {
+      @if (loading) {
         <tr>
           <td colspan="5">
             <div class="spinner-border spinner-border-sm me-2" role="status"></div>
   </table>
 </div>
 
-@if (!isLoading) {
+@if (!loading) {
   <div class="d-flex mb-2">
     @if (collectionSize > 0) {
       <div>
index 50ae1c86b58a52f570e69f9588d35f2dc56d7b6c..164b2fa527e714a883cfba4007d8d404090ca092 100644 (file)
@@ -39,8 +39,8 @@ import {
 import { ToastService } from 'src/app/services/toast.service'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
 import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
 import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 export interface ManagementListColumn {
   key: string
@@ -56,7 +56,7 @@ export interface ManagementListColumn {
 
 @Directive()
 export abstract class ManagementListComponent<T extends ObjectWithId>
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit, OnDestroy
 {
   constructor(
@@ -86,8 +86,6 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
   public sortField: string
   public sortReverse: boolean
 
-  public isLoading: boolean = false
-
   private nameFilterDebounce: Subject<string>
   protected unsubscribeNotifier: Subject<any> = new Subject()
   protected _nameFilter: string
@@ -95,8 +93,6 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
   public selectedObjects: Set<number> = new Set()
   public togggleAll: boolean = false
 
-  public reveal: boolean = false
-
   ngOnInit(): void {
     this.reloadData()
 
@@ -115,11 +111,6 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
       })
   }
 
-  ngOnDestroy() {
-    this.unsubscribeNotifier.next(true)
-    this.unsubscribeNotifier.complete()
-  }
-
   getMatching(o: MatchingModel) {
     if (o.matching_algorithm == MATCH_AUTO) {
       return $localize`Automatic`
@@ -141,7 +132,7 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
   }
 
   reloadData(extraParams: { [key: string]: any } = null) {
-    this.isLoading = true
+    this.loading = true
     this.clearSelection()
     this.service
       .listFiltered(
@@ -163,7 +154,7 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
       )
       .subscribe(() => {
         this.reveal = true
-        this.isLoading = false
+        this.loading = false
       })
   }
 
index dc09c71e4671bebc5f018e81c49d615f979b8de3..ba72cb6e5b2e56c16518b30db0c7ecb9b5f91c57 100644 (file)
@@ -3,11 +3,11 @@ import { FormControl, FormGroup } from '@angular/forms'
 import { SavedView } from 'src/app/data/saved-view'
 import { SavedViewService } from 'src/app/services/rest/saved-view.service'
 import { SettingsService } from 'src/app/services/settings.service'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
 import { DisplayMode } from 'src/app/data/document'
-import { BehaviorSubject, Observable, Subject, Subscription } from 'rxjs'
+import { BehaviorSubject, Observable, takeUntil } from 'rxjs'
 import { dirtyCheck } from '@ngneat/dirty-check-forms'
 import { ToastService } from 'src/app/services/toast.service'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-saved-views',
@@ -15,7 +15,7 @@ import { ToastService } from 'src/app/services/toast.service'
   styleUrl: './saved-views.component.scss',
 })
 export class SavedViewsComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit, OnDestroy
 {
   DisplayMode = DisplayMode
@@ -27,11 +27,7 @@ export class SavedViewsComponent
   })
 
   private store: BehaviorSubject<any>
-  private storeSub: Subscription
   public isDirty$: Observable<boolean>
-  private isDirty: boolean = false
-  private unsubscribeNotifier: Subject<any> = new Subject()
-  private savePending: boolean = false
 
   get displayFields() {
     return this.settings.allDisplayFields
@@ -56,9 +52,7 @@ export class SavedViewsComponent
 
   ngOnDestroy(): void {
     this.settings.organizingSidebarSavedViews = false
-    this.unsubscribeNotifier.next(this)
-    this.unsubscribeNotifier.complete()
-    this.storeSub.unsubscribe()
+    super.ngOnDestroy()
   }
 
   private initialize() {
@@ -93,9 +87,12 @@ export class SavedViewsComponent
     }
 
     this.store = new BehaviorSubject(storeData)
-    this.storeSub = this.store.asObservable().subscribe((state) => {
-      this.savedViewsForm.patchValue(state, { emitEvent: false })
-    })
+    this.store
+      .asObservable()
+      .pipe(takeUntil(this.unsubscribeNotifier))
+      .subscribe((state) => {
+        this.savedViewsForm.patchValue(state, { emitEvent: false })
+      })
 
     // Initialize dirtyCheck
     this.isDirty$ = dirtyCheck(this.savedViewsForm, this.store.asObservable())
index 106b99485580b824db616bf2b0745abba4a88ca2..1c04ff5d122eed7e60837d145577bbec37822d92 100644 (file)
@@ -1,7 +1,6 @@
 import { Component, OnInit } from '@angular/core'
 import { WorkflowService } from 'src/app/services/rest/workflow.service'
-import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
-import { delay, Subject, takeUntil, tap } from 'rxjs'
+import { delay, takeUntil, tap } from 'rxjs'
 import { Workflow } from 'src/app/data/workflow'
 import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
 import { ToastService } from 'src/app/services/toast.service'
@@ -12,6 +11,7 @@ import {
 } from '../../common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component'
 import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
 import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
+import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
 
 @Component({
   selector: 'pngx-workflows',
@@ -19,16 +19,11 @@ import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
   styleUrls: ['./workflows.component.scss'],
 })
 export class WorkflowsComponent
-  extends ComponentWithPermissions
+  extends LoadingComponentWithPermissions
   implements OnInit
 {
   public workflows: Workflow[] = []
 
-  private unsubscribeNotifier: Subject<any> = new Subject()
-
-  public loading: boolean = false
-  public reveal: boolean = false
-
   constructor(
     private workflowService: WorkflowService,
     public permissionsService: PermissionsService,