1- import { Modal } from "obsidian" ;
1+ import { LocalSettings } from "cdm/SettingsModel" ;
2+ import { generateDbConfiguration , generateNewDatabase } from "helpers/CommandsHelper" ;
3+ import { InputType , SourceDataTypes , StyleClasses } from "helpers/Constants" ;
4+ import { resolve_tfolder } from "helpers/FileManagement" ;
5+ import { generateDataviewTableQuery } from "helpers/QueryHelper" ;
6+ import { Modal , Notice , Setting , TFolder } from "obsidian" ;
7+ import { DataviewService } from "services/DataviewService" ;
8+ import { add_dropdown , add_setting_header } from "settings/SettingsComponents" ;
9+ import { FileSuggest } from "settings/suggesters/FileSuggester" ;
10+ import { FolderSuggest } from "settings/suggesters/FolderSuggester" ;
211
312export class DatabaseHelperCreationModal extends Modal {
413 databaseHelperCreationModalManager : DatabaseHelperCreationModalManager ;
5- constructor ( ) {
14+ local_settings : LocalSettings ;
15+ constructor ( local_settings : LocalSettings ) {
616 super ( app ) ;
17+ this . local_settings = local_settings ;
718 this . databaseHelperCreationModalManager = new DatabaseHelperCreationModalManager ( this ) ;
819 }
920 onOpen ( ) {
@@ -20,11 +31,225 @@ export class DatabaseHelperCreationModal extends Modal {
2031
2132export class DatabaseHelperCreationModalManager {
2233 databaseHelperCreationModal : DatabaseHelperCreationModal ;
34+ destinationFolder = '/' ;
35+ databaseName = '' ;
2336 constructor (
2437 databaseHelperCreationModal : DatabaseHelperCreationModal ,
2538 ) {
2639 this . databaseHelperCreationModal = databaseHelperCreationModal ;
40+
41+
2742 }
2843 constructUI ( containerEl : HTMLElement ) {
44+ add_setting_header ( containerEl , "Database creator helper" , 'h2' ) ;
45+ const helperBody = containerEl . createDiv ( ) ;
46+ helperBody . addClass ( StyleClasses . SETTINGS_MODAL_BODY ) ;
47+ helperBody . setAttribute ( "id" , StyleClasses . SETTINGS_MODAL_BODY ) ;
48+ this . constructSettingBody ( helperBody ) ;
2949 }
30- }
50+
51+ constructSettingBody ( bodyElement : HTMLElement ) {
52+ new Setting ( bodyElement )
53+ . setName ( "Database name" )
54+ . setDesc ( "Name of the database to create" )
55+ . addText ( text => {
56+ text . setPlaceholder ( "Database name" )
57+ . setValue ( this . databaseName )
58+ . onChange ( async ( value : string ) : Promise < void > => {
59+ this . databaseName = this . parseValueToThuthyYaml ( value ) ;
60+ } ) ;
61+ } ) ;
62+
63+ add_dropdown (
64+ bodyElement ,
65+ 'Select source' ,
66+ 'Select from which source you want to create your custom database.' ,
67+ this . databaseHelperCreationModal . local_settings . source_data ,
68+ {
69+ current_folder : SourceDataTypes . CURRENT_FOLDER ,
70+ tag : SourceDataTypes . TAG ,
71+ outgoing_link : SourceDataTypes . OUTGOING_LINK ,
72+ incoming_link : SourceDataTypes . INCOMING_LINK ,
73+ query : SourceDataTypes . QUERY ,
74+ } ,
75+ async ( value : string ) => {
76+ this . databaseHelperCreationModal . local_settings . source_data = value ;
77+ this . reset ( ) ;
78+ }
79+ ) ;
80+ switch ( this . databaseHelperCreationModal . local_settings . source_data ) {
81+ case SourceDataTypes . TAG :
82+ this . tagHandler ( bodyElement ) ;
83+ break ;
84+ case SourceDataTypes . INCOMING_LINK :
85+ case SourceDataTypes . OUTGOING_LINK :
86+ this . outgoingAndIncomingHandler ( bodyElement ) ;
87+ break ;
88+ case SourceDataTypes . QUERY :
89+ this . queryHandler ( bodyElement ) ;
90+ break ;
91+ default :
92+ // do nothing
93+ }
94+
95+ new Setting ( bodyElement )
96+ . setName ( 'Select where to save your database' )
97+ . setDesc ( 'Select the destination of where you want to save your database.' )
98+ . addSearch ( ( cb ) => {
99+ new FolderSuggest (
100+ cb . inputEl
101+ ) ;
102+ cb . setPlaceholder ( "Example: path/to/folder" )
103+ . setValue ( this . destinationFolder )
104+ . onChange ( ( value : string ) => {
105+ this . destinationFolder = value ;
106+ } ) ;
107+ } ) ;
108+
109+ new Setting ( bodyElement )
110+ . setName ( 'Submit' )
111+ . setDesc ( 'Close to cancel or submit to create your database.' )
112+ . addButton ( ( cb ) => {
113+ cb . setButtonText ( 'Close' )
114+ . onClick ( ( ) => {
115+ this . databaseHelperCreationModal . close ( ) ;
116+ } ) ;
117+ } ) . addButton ( ( cb ) => {
118+ cb . setButtonText ( 'Create' )
119+ . onClick ( async ( ) => {
120+ await this . createButtonHandler ( )
121+ } ) ;
122+ } ) ;
123+ }
124+
125+ reset ( ) {
126+ const bodyElement = activeDocument . getElementById ( StyleClasses . SETTINGS_MODAL_BODY ) ;
127+ // remove all sections
128+ bodyElement . empty ( ) ;
129+ this . constructSettingBody ( bodyElement ) ;
130+ }
131+
132+ async createButtonHandler ( ) {
133+ try {
134+ const targetFolder = resolve_tfolder ( this . destinationFolder ) ;
135+ this . databaseHelperCreationModal . local_settings . source_form_result = this . parseValueToThuthyYaml (
136+ this . databaseHelperCreationModal . local_settings . source_form_result
137+ ) ;
138+ await generateNewDatabase (
139+ generateDbConfiguration ( this . databaseHelperCreationModal . local_settings ) ,
140+ targetFolder ,
141+ this . databaseName
142+ ) ;
143+ new Notice ( `Database "${ this . databaseName } " created in "${ targetFolder . path } "` , 1500 ) ;
144+ } catch ( e ) {
145+ new Notice ( `Error creating database "${ this . databaseName } ": ${ e } ` , 1500 ) ;
146+ }
147+ this . databaseHelperCreationModal . close ( ) ;
148+ }
149+
150+ tagHandler ( containerEl : HTMLElement ) {
151+ const tagArray : Record < string , number > = ( app . metadataCache as unknown as any ) . getTags ( ) ;
152+ if ( tagArray ) {
153+ const tagRecords : Record < string , string > = { } ;
154+ // Order tagRecord by key (tag name)
155+ Object . entries ( tagArray )
156+ . sort ( ( a , b ) => a [ 0 ] . localeCompare ( b [ 0 ] ) )
157+ . forEach ( ( [ key , value ] ) => {
158+ tagRecords [ key ] = `${ key } (${ value } )` ;
159+ } ) ;
160+ const source_form_promise = async ( value : string ) : Promise < void > => {
161+ // update form result
162+ this . databaseHelperCreationModal . local_settings . source_form_result = value . slice ( 1 ) ;
163+ } ;
164+
165+ add_dropdown (
166+ containerEl ,
167+ 'Select a tag' ,
168+ 'Select tag to get data from' ,
169+ `#${ this . databaseHelperCreationModal . local_settings . source_form_result } ` ,
170+ tagRecords ,
171+ source_form_promise
172+ ) ;
173+ this . destinationFolderHandler ( containerEl ) ;
174+ }
175+ }
176+
177+ queryHandler ( containerEl : HTMLElement ) {
178+ const query_promise = async ( value : string ) : Promise < void > => {
179+ // update settings
180+ this . databaseHelperCreationModal . local_settings . source_form_result = value ;
181+ } ;
182+ new Setting ( containerEl )
183+ . setName ( 'Dataview query' )
184+ . setDesc ( 'Enter a dataview query starting with FROM (the plugin autocomplete the query with TABLE & the column fields)' )
185+ . addTextArea ( ( textArea ) => {
186+ textArea . setValue ( this . databaseHelperCreationModal . local_settings . source_form_result ) ;
187+ textArea . setPlaceholder ( 'Write here your dataview query...' ) ;
188+ textArea . onChange ( query_promise ) ;
189+ } ) . addExtraButton ( ( cb ) => {
190+ cb . setIcon ( "check" )
191+ . setTooltip ( "Validate query" )
192+ . onClick ( async ( ) : Promise < void > => {
193+ const query = generateDataviewTableQuery (
194+ [ ] ,
195+ this . databaseHelperCreationModal . local_settings . source_form_result ) ;
196+ if ( query ) {
197+ DataviewService . getDataviewAPI ( ) . tryQuery ( query . replace ( 'TABLE ,' , 'TABLE ' ) )
198+ . then ( ( ) => {
199+ new Notice ( `Dataview query "${ query } " is valid!` , 2000 ) ;
200+ } )
201+ . catch ( ( e ) => {
202+ new Notice ( `Dataview query "${ query } " is invalid: ${ e . message } ` , 10000 ) ;
203+ } ) ;
204+ }
205+ } ) ;
206+ } ) ;
207+ this . destinationFolderHandler ( containerEl ) ;
208+ }
209+
210+ outgoingAndIncomingHandler ( containerEl : HTMLElement ) {
211+ const source_form_promise = async ( value : string ) : Promise < void > => {
212+ // update form result
213+ this . databaseHelperCreationModal . local_settings . source_form_result = value ;
214+ } ;
215+ new Setting ( containerEl )
216+ . setName ( 'Select a file' )
217+ . setDesc ( 'Select file from vault to be used as source of data.' )
218+ . addSearch ( ( cb ) => {
219+ new FileSuggest (
220+ cb . inputEl ,
221+ "/"
222+ ) ;
223+ cb . setPlaceholder ( "Example: folder1/template_file" )
224+ . setValue ( this . databaseHelperCreationModal . local_settings . source_form_result )
225+ . onChange ( source_form_promise ) ;
226+ } ) ;
227+ this . destinationFolderHandler ( containerEl ) ;
228+ }
229+
230+ destinationFolderHandler ( containerEl : HTMLElement ) {
231+ const source_form_promise = async ( value : string ) : Promise < void > => {
232+ // update settings
233+ this . databaseHelperCreationModal . local_settings . source_destination_path = value ;
234+ } ;
235+ new Setting ( containerEl )
236+ . setName ( 'Select destination folder' )
237+ . setDesc ( 'Select the destination of new entries for this source' )
238+ . addSearch ( ( cb ) => {
239+ new FolderSuggest (
240+ cb . inputEl
241+ ) ;
242+ cb . setPlaceholder ( "Example: path/to/folder" )
243+ . setValue ( this . databaseHelperCreationModal . local_settings . source_destination_path )
244+ . onChange ( source_form_promise ) ;
245+ } ) ;
246+ }
247+
248+ parseValueToThuthyYaml ( value : string ) : string {
249+ return DataviewService . parseLiteral (
250+ value ,
251+ InputType . MARKDOWN ,
252+ this . databaseHelperCreationModal . local_settings
253+ ) . toString ( ) ;
254+ }
255+ }
0 commit comments