Frontend: Refactor source name translations in the edit dialog

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer
2025-09-03 16:11:53 +02:00
parent f5a4aacc5c
commit 22d7e65f3f
50 changed files with 16827 additions and 16656 deletions

View File

@@ -10,5 +10,6 @@ export const Xmp = "xmp";
export const Yaml = "yaml"; export const Yaml = "yaml";
export const Marker = "marker"; export const Marker = "marker";
export const Image = "image"; export const Image = "image";
export const Vision = "vision";
export const Keyword = "keyword"; export const Keyword = "keyword";
export const Location = "location"; export const Location = "location";

View File

@@ -703,6 +703,54 @@ export default class $util {
} }
} }
// Returns the translated source name string to be displayed in the user interface.
static sourceName(src, defaultValue) {
switch (src) {
case null:
case false:
case undefined:
case "":
case "auto":
return defaultValue ? defaultValue : $gettext("Auto");
case "default":
return $gettext("Default");
case "estimate":
return $gettext("Estimate");
case "file":
return $gettext("File");
case "name":
return $gettext("Name");
case "image":
return $gettext("Image");
case "location":
return $gettext("Location");
case "marker":
return $gettext("Marker");
case "caption":
return $gettext("Caption");
case "keyword":
return $gettext("Keyword");
case "meta":
return $gettext("Metadata");
case "subject":
return $gettext("Subject");
case "title":
return $gettext("Title");
case "xmp":
return "XMP";
case "batch":
return $gettext("Batch");
case "manual":
return $gettext("Manual");
case "vision":
return $gettext("Vision");
case "admin":
return $gettext("Admin");
default:
return this.ucFirst(src);
}
}
// Returns the best matching thumbnail based on the provided list of available images, // Returns the best matching thumbnail based on the provided list of available images,
// as well as the viewport width and height. // as well as the viewport width and height.
static thumb(thumbs, viewportWidth, viewportHeight) { static thumb(thumbs, viewportWidth, viewportHeight) {

View File

@@ -262,7 +262,9 @@
<td> <td>
{{ $gettext(`Projection`) }} {{ $gettext(`Projection`) }}
</td> </td>
<td class="text-capitalize">{{ file.Projection }}</td> <td class="text-capitalize">
{{ file.Projection }}
</td>
</tr> </tr>
<tr v-if="file.AspectRatio"> <tr v-if="file.AspectRatio">
<td> <td>
@@ -323,7 +325,9 @@
<td> <td>
{{ $gettext(`Main Color`) }} {{ $gettext(`Main Color`) }}
</td> </td>
<td class="text-capitalize">{{ file.MainColor }}</td> <td class="text-capitalize">
{{ file.MainColor }}
</td>
</tr> </tr>
<tr v-if="file?.Chroma > 0"> <tr v-if="file?.Chroma > 0">
<td> <td>
@@ -400,6 +404,7 @@ export default {
default: "", default: "",
}, },
}, },
emits: ["close"],
data() { data() {
return { return {
view: this.$view.getData(), view: this.$view.getData(),
@@ -426,7 +431,12 @@ export default {
align: "center", align: "center",
class: "p-col-primary", class: "p-col-primary",
}, },
{ title: this.$gettext("Name"), key: "Name", sortable: false, align: "left" }, {
title: this.$gettext("Name"),
key: "Name",
sortable: false,
align: "left",
},
{ {
title: this.$gettext("Dimensions"), title: this.$gettext("Dimensions"),
headerProps: { headerProps: {
@@ -443,8 +453,18 @@ export default {
key: "Size", key: "Size",
sortable: false, sortable: false,
}, },
{ title: this.$gettext("Type"), key: "", sortable: false, align: "left" }, {
{ title: this.$gettext("Status"), key: "", sortable: false, align: "left" }, title: this.$gettext("Type"),
key: "",
sortable: false,
align: "left",
},
{
title: this.$gettext("Status"),
key: "",
sortable: false,
align: "left",
},
], ],
}; };
}, },

View File

@@ -24,7 +24,7 @@
<td> <td>
<span>{{ $gettext(`Type`) }}</span> <span>{{ $gettext(`Type`) }}</span>
</td> </td>
<td v-tooltip="formatSource(view.model?.TypeSrc, $gettext('Default'))"> <td v-tooltip="sourceName(view.model?.TypeSrc, $gettext('Default'))">
<v-select <v-select
v-model="view.model.Type" v-model="view.model.Type"
:append-icon="view.model.TypeSrc === 'manual' ? 'mdi-check' : ''" :append-icon="view.model.TypeSrc === 'manual' ? 'mdi-check' : ''"
@@ -87,7 +87,7 @@
<span>{{ $gettext(`Title`) }}</span> <span>{{ $gettext(`Title`) }}</span>
</td> </td>
<td> <td>
<div v-tooltip="formatSource(view.model?.TitleSrc, $gettext('Generated'))" class="text-flex text-break"> <div v-tooltip="sourceName(view.model?.TitleSrc, $gettext('Generated'))" class="text-flex text-break">
<span class="cursor-copy text-break" @click.stop.prevent="$util.copyText(view.model.Title)">{{ <span class="cursor-copy text-break" @click.stop.prevent="$util.copyText(view.model.Title)">{{
view.model.Title view.model.Title
}}</span> }}</span>
@@ -101,7 +101,7 @@
<span>{{ $gettext(`Taken`) }}</span> <span>{{ $gettext(`Taken`) }}</span>
</td> </td>
<td> <td>
<div v-tooltip="formatSource(view.model?.TakenSrc, $gettext('File'))" class="text-flex text-break"> <div v-tooltip="sourceName(view.model?.TakenSrc, $gettext('File'))" class="text-flex text-break">
<div>{{ view.model.getDateString() }}</div> <div>{{ view.model.getDateString() }}</div>
<v-icon v-if="view.model.TakenSrc === ''" icon="mdi-file-clock-outline" class="src"></v-icon> <v-icon v-if="view.model.TakenSrc === ''" icon="mdi-file-clock-outline" class="src"></v-icon>
<!-- v-icon v-else-if="view.model.TakenSrc === 'meta'" icon="mdi-camera" class="src"></v-icon --> <!-- v-icon v-else-if="view.model.TakenSrc === 'meta'" icon="mdi-camera" class="src"></v-icon -->
@@ -224,7 +224,7 @@
{{ $gettext(`Place`) }} {{ $gettext(`Place`) }}
</td> </td>
<td> <td>
<div v-tooltip="formatSource(view.model.PlaceSrc, $gettext('Missing'))" class="text-flex"> <div v-tooltip="sourceName(view.model.PlaceSrc, $gettext('Missing'))" class="text-flex">
<div>{{ view.model.locationInfo() }}</div> <div>{{ view.model.locationInfo() }}</div>
<v-icon v-if="view.model.PlaceSrc === 'estimate'" icon="mdi-map-clock-outline" class="src"></v-icon> <v-icon v-if="view.model.PlaceSrc === 'estimate'" icon="mdi-map-clock-outline" class="src"></v-icon>
<!-- v-icon v-else-if="view.model.PlaceSrc === 'meta'" icon="mdi-camera" class="src"></v-icon --> <!-- v-icon v-else-if="view.model.PlaceSrc === 'meta'" icon="mdi-camera" class="src"></v-icon -->
@@ -360,41 +360,8 @@ export default {
}, },
methods: { methods: {
$gettext, $gettext,
formatSource(s, defaultValue) { sourceName(src, defaultValue) {
switch (s) { return this.$util.sourceName(src, defaultValue);
case null:
case false:
case undefined:
case "":
case "auto":
return defaultValue ? defaultValue : this.$gettext("Auto");
case "default":
return this.$gettext("Default");
case "batch":
return this.$gettext("Batch");
case "manual":
return this.$gettext("Manual");
case "meta":
return this.$gettext("Metadata");
case "xmp":
return "XMP";
case "estimate":
return this.$gettext("Estimate");
case "file":
return this.$gettext("File");
case "name":
return this.$gettext("Name");
case "title":
return this.$gettext("Title");
case "caption":
return this.$gettext("Caption");
case "image":
return this.$gettext("Image");
case "location":
return this.$gettext("Location");
default:
return T(this.$util.capitalize(s));
}
}, },
formatTime(s) { formatTime(s) {
return DateTime.fromISO(s, { zone: this.timeZone }).toLocaleString(formats.TIMESTAMP); return DateTime.fromISO(s, { zone: this.timeZone }).toLocaleString(formats.TIMESTAMP);

View File

@@ -192,6 +192,7 @@ export default {
default: "", default: "",
}, },
}, },
emits: ["close"],
data() { data() {
return { return {
view: this.$view.getData(), view: this.$view.getData(),
@@ -201,15 +202,30 @@ export default {
selected: [], selected: [],
newLabel: "", newLabel: "",
listColumns: [ listColumns: [
{ title: this.$gettext("Label"), key: "", sortable: false, align: "left" }, {
{ title: this.$gettext("Source"), key: "LabelSrc", sortable: false, align: "left" }, title: this.$gettext("Label"),
key: "",
sortable: false,
align: "left",
},
{
title: this.$gettext("Source"),
key: "LabelSrc",
sortable: false,
align: "left",
},
{ {
title: this.$gettext("Confidence"), title: this.$gettext("Confidence"),
key: "Uncertainty", key: "Uncertainty",
sortable: false, sortable: false,
align: "center", align: "center",
}, },
{ title: this.$gettext("Action"), key: "", sortable: false, align: "center" }, {
title: this.$gettext("Action"),
key: "",
sortable: false,
align: "center",
},
], ],
nameRule: (v) => v.length <= this.$config.get("clip") || this.$gettext("Name too long"), nameRule: (v) => v.length <= this.$config.get("clip") || this.$gettext("Name too long"),
}; };
@@ -217,24 +233,7 @@ export default {
methods: { methods: {
refresh() {}, refresh() {},
sourceName(s) { sourceName(s) {
switch (s) { return this.$util.sourceName(s);
case "batch":
return this.$gettext("Batch");
case "manual":
return this.$gettext("Manual");
case "title":
return this.$gettext("Title");
case "caption":
return this.$gettext("Caption");
case "subject":
return this.$gettext("Subject");
case "image":
return this.$gettext("Image");
case "location":
return this.$gettext("Location");
default:
return this.$util.ucFirst(s);
}
}, },
removeLabel(label) { removeLabel(label) {
if (!label || !this.view?.model) { if (!label || !this.view?.model) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff