feat: work on moving logic

This commit is contained in:
Al0cam 2025-11-02 18:39:34 +01:00
parent b12444aeff
commit 7135c5181e
4 changed files with 138 additions and 86 deletions

View file

@ -50,7 +50,6 @@ export function projectSection(containerEl: HTMLElement, plugin: AutoMoverPlugin
*/
for (const project of plugin.settings.projectRules as ProjectRule[]) {
const child = projectList.createDiv({ cls: "project" });
const projectDetails = child.createDiv({ cls: "rule" });
// Class used from obdsidian's css for consistency
const movingRulesDetails = child.createEl("details", {});
@ -149,7 +148,5 @@ export function projectSection(containerEl: HTMLElement, plugin: AutoMoverPlugin
display();
});
}
projectDetails.createEl("br");
}
}

View file

@ -0,0 +1,45 @@
import { ProjectRule } from "Models/ProjectRule";
import type { TFile } from "obsidian";
import propertyUtil from "./PropertyUtil";
class ProjectMatcherUtil {
private static instance: ProjectMatcherUtil;
private constructor() {}
public static getInstance(): ProjectMatcherUtil {
if (!ProjectMatcherUtil.instance) {
ProjectMatcherUtil.instance = new ProjectMatcherUtil();
}
return ProjectMatcherUtil.instance;
}
/**
* Returns the first project rule that matches the file
* If no rule matches, returns null
* @param file
* @param projectRules
* @returns ProjectRule | null
*/
public getMatchingProjectRule(file: TFile, projectRules: ProjectRule[]): ProjectRule | null {
propertyUtil.getPropertiesFromFile(file);
for (const rule of projectRules) {
if (rule.projectName == null || rule.projectName === "") {
console.error("Project Rule does not have a project name: ", rule);
continue;
}
if (rule.folder == null || rule.folder === "") {
console.error("Project Rule does not have a destination folder: ", rule);
continue;
}
// Check if the file path contains the project name as a wiki link or plain text
const wikiLink = `[[${rule.projectName}]]`;
if (file.path.includes(wikiLink) || file.path.includes(rule.projectName)) {
return rule;
}
}
return null;
}
}
const exclusionMatcherUtil = ProjectMatcherUtil.getInstance();
export default exclusionMatcherUtil;

View file

@ -1,3 +1,5 @@
import { TFile } from "obsidian";
class PropertyUtil {
private static instance: PropertyUtil;
@ -10,23 +12,31 @@ class PropertyUtil {
return PropertyUtil.instance;
}
/**
* TODO: Add property support
*
* overview.md
* Page Properties:
* Project: [[Project A]]
* File Type: asset
*
* It would take those Project Property and File Type Properties, moving it to Project A/assets.
*
*
*
* Theoretically, projects should then take precedence over tags and names, as they are more specific.
*
*
* The way i see the implementation is adding a new model that will contain the project destination
* and then specify in subdirectories where each matching file goes.
* And it has to check if the file contains the property from the project such as it was mentioned in the overview.md example.
*
*/
/**
* TODO: Add property support
*
* overview.md
* Page Properties:
* Project: [[Project A]]
* File Type: asset
*
* It would take those Project Property and File Type Properties, moving it to Project A/assets.
*
*
*
* Theoretically, projects should then take precedence over tags and names, as they are more specific.
*
*/
public getPropertiesFromFile(file: TFile): Record<string, string> {
console.log("Extracted properties: ", properties);
return properties;
}
}
const propertyUtil = PropertyUtil.getInstance();

View file

@ -8,118 +8,118 @@ If your plugin does not need CSS, delete this file.
*/
.moving_rules_container {
padding: 0.75em 0;
border-top: 1px solid var(--background-modifier-border);
display: flex;
flex-direction: column;
padding: 0.75em 0;
border-top: 1px solid var(--background-modifier-border);
display: flex;
flex-direction: column;
}
.rule {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.5em;
justify-content: space-evenly;
gap: 0.5em;
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.5em;
justify-content: space-evenly;
gap: 0.5em;
}
.rule_header {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}
.rule_title {
padding: 0.5em;
width: 100%;
font-weight: bold;
padding: 0.5em;
width: 100%;
font-weight: bold;
}
.rule_input {
width: 100%;
padding: 0.5em;
border: 1px solid var(--background-modifier-border);
border-radius: 0.25em;
width: 100%;
padding: 0.5em;
border: 1px solid var(--background-modifier-border);
border-radius: 0.25em;
}
.rule_button {
cursor: pointer;
cursor: pointer;
}
.rule_button:hover {
background-color: var(--color-green);
background-color: var(--color-green);
}
.rule_button:active {
background-color: var(--background-modifier-active);
background-color: var(--background-modifier-active);
}
.rule_button_remove:hover {
background-color: var(--color-red) !important;
background-color: var(--color-red) !important;
}
.rule_button_duplicate:hover {
background-color: var(--color-blue) !important;
background-color: var(--color-blue) !important;
}
/* Style for timer-setting input field */
.setting-item.timer-setting input[type="text"] {
width: auto;
min-width: 8ch;
/* Minimum for hh:mm:ss */
max-width: 16ch;
/* Allows up to ~9999:59:59 */
/* padding: 2px 6px; */
font-family: monospace;
text-align: center;
/* box-sizing: content-box; */
width: auto;
min-width: 8ch;
/* Minimum for hh:mm:ss */
max-width: 16ch;
/* Allows up to ~9999:59:59 */
/* padding: 2px 6px; */
font-family: monospace;
text-align: center;
/* box-sizing: content-box; */
}
.project {
display: flex;
flex-direction: column;
gap: 0.5em;
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 0.75em;
padding-top: 0.75em;
display: flex;
flex-direction: column;
gap: 0.5em;
border-bottom: 1px solid var(--background-modifier-border);
padding-bottom: 0.75em;
padding-top: 0.75em;
}
.project_rule {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.5em;
margin-left: 1em;
justify-content: space-evenly;
gap: 0.5em;
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 0.5em;
margin-left: 3em;
justify-content: space-evenly;
gap: 0.5em;
}
summary {
/* Hides the marker in most browsers */
list-style: none;
/* Hides the marker in Safari/WebKit */
/* This is crucial for cross-browser consistency */
-webkit-appearance: none;
/* Hides the marker in most browsers */
list-style: none;
/* Hides the marker in Safari/WebKit */
/* This is crucial for cross-browser consistency */
-webkit-appearance: none;
}
/* Add a custom icon using ::before */
summary::before {
content: "▶";
/* Closed state icon */
margin-right: 10px;
/* Position the arrow before the content */
display: inline-block;
transition: transform 0.2s;
/* Customize the look/color of the arrow */
color: #fff;
min-width: 12px;
/* Ensure it doesn't shift */
content: "▶";
/* Closed state icon */
margin-right: 10px;
/* Position the arrow before the content */
display: inline-block;
transition: transform 0.2s;
/* Customize the look/color of the arrow */
color: #fff;
min-width: 12px;
/* Ensure it doesn't shift */
}
/* Rotate the icon when the details is open */
details[open]>summary::before {
transform: rotate(90deg);
/* Rotates the '▶' into a '▼' */
details[open] > summary::before {
transform: rotate(90deg);
/* Rotates the '▶' into a '▼' */
}