Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions tools/cldr-apps/js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tools/cldr-apps/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"glyphicons-only-bootstrap": "^1.0.1",
"marked": "^4.3.0",
"swagger-client": "^3.26.7",
"unicode-name": "^1.1.0",
"vue": "^3.2.47",
"vue-virtual-scroller": "^2.0.0-beta.8",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
Expand Down
147 changes: 101 additions & 46 deletions tools/cldr-apps/js/src/views/AddValue.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,100 @@
<template>
<!-- If use a-button instead of button, form positioning fails -->
<button class="plus" type="button" @click="showModal">
<!-- U+271A HEAVY GREEK CROSS -->
</button>
<a-modal
v-model:visible="formIsVisible"
:closable="false"
:footer="null"
class="dialog"
:style="{
position: 'sticky',
left: formLeft + 'px',
top: formTop + 'px',
}"
@ok="onSubmit"
>
<p>
<a-config-provider :direction="dir">
<template v-if="inputModeIsTags">
<component
:is="AddValueTags"
:key="componentKey"
v-model="newValue"
ref="tagsRef"
@change="handleTagsChange"
/>
</template>
<template v-else>
<!-- input mode is Text -->
<a-input
v-model:value="newValue"
placeholder="Add a translation"
ref="inputToFocus"
@keydown.enter="onSubmit"
/>
</template>
</a-config-provider>
</p>

<p>
<label for="radio_mode">Input mode:&nbsp;&nbsp;</label>
<a-radio-group id="radio_mode" v-model:value="inputModeIsTags">
<a-tooltip placement="bottom">
<template #title>{{ textHelp }}</template>
<a-radio :value="false">Text</a-radio>
</a-tooltip>
<a-tooltip placement="bottom">
<template #title>{{ tagHelp }}</template>
<a-radio :value="true">Tags</a-radio>
</a-tooltip>
</a-radio-group>
</p>

<div class="button-container">
<a-button @click="onEnglish">→English</a-button>
<a-button @click="onWinning">→Winning</a-button>
<button
class="plus"
type="button"
@click="voteForMissing"
v-if="showVoteForMissing"
>
{{ cldrConstants.VOTE_FOR_MISSING }} - vote for missing
</button>
<a-button type="cancel" @click="onCancel">Cancel</a-button>
<a-button type="primary" @click="onSubmit">Submit</a-button>
</div>
</a-modal>
</template>

<script setup>
import { nextTick, ref } from "vue";

import AddValueTags from "./AddValueTags.vue";

import * as cldrAddValue from "../esm/cldrAddValue.mjs";
import * as cldrConstants from "../esm/cldrConstants.mjs";
import * as cldrStatus from "../esm/cldrStatus.mjs";

const textHelp =
"Show the value as a text string, which can be edited using the ordinary editing features of the web browser";

const tagHelp =
"Show the value as a sequence of tags, each tag representing a character, with special features for viewing/editing tags";

const xpstrid = ref(""); // xpath string id
const newValue = ref("");
const formLeft = ref(0);
const formTop = ref(0);
const formIsVisible = ref(false);
const inputToFocus = ref(null);
const inputModeIsTags = ref(false);
const componentKey = ref(0);
const tagsRef = ref();

const showVoteForMissing = ref(
cldrStatus.getPermissions()?.userCanVoteForMissing
);
Expand All @@ -25,24 +109,28 @@ function showModal(event) {
// Use the coordinates of the button's top-left corner
formLeft.value = event.clientX - event.offsetX;
formTop.value = event.clientY - event.offsetY;
newValue.value = "";
setValue("");
formIsVisible.value = true;
cldrAddValue.setFormIsVisible(true, xpstrid.value);
nextTick(focusInput);
}

function setValue(s) {
newValue.value = s;
}

function focusInput() {
if (inputToFocus.value) {
inputToFocus.value.focus();
}
}

function onEnglish() {
newValue.value = cldrAddValue.getEnglish(xpstrid.value);
setValue(cldrAddValue.getEnglish(xpstrid.value));
}

function onWinning() {
newValue.value = cldrAddValue.getWinning(xpstrid.value);
setValue(cldrAddValue.getWinning(xpstrid.value));
}

function onCancel() {
Expand All @@ -59,56 +147,23 @@ function onSubmit() {
}

function voteForMissing() {
newValue.value = cldrConstants.VOTE_FOR_MISSING;
setValue(cldrConstants.VOTE_FOR_MISSING);
}

function handleTagsChange() {
// Incrementing the componentKey forces re-rendering. Otherwise reactive update
// fails for unknown reasons under some circumstances. For example, when a tag is
// deleted, if re-rendering is not forced, sometimes two adjacent [+] controls are
// displayed, which should not be the case. Reference:
// https://michaelnthiessen.com/force-re-render/#better-way-you-can-use-forceupdate
componentKey.value++;
}

defineExpose({
setXpathStringId,
});
</script>

<template>
<!-- If use a-button instead of button, form positioning fails -->
<button class="plus" type="button" @click="showModal">
<!-- U+271A HEAVY GREEK CROSS -->
</button>
<a-modal
v-model:visible="formIsVisible"
:closable="false"
:footer="null"
:style="{
position: 'sticky',
left: formLeft + 'px',
top: formTop + 'px',
}"
@ok="onSubmit"
>
<a-config-provider :direction="dir">
<a-input
v-model:value="newValue"
placeholder="Add a translation"
ref="inputToFocus"
@keydown.enter="onSubmit"
/>
</a-config-provider>
<div class="button-container">
<a-button @click="onEnglish">→English</a-button>
<a-button @click="onWinning">→Winning</a-button>
<button
class="plus"
type="button"
@click="voteForMissing"
v-if="showVoteForMissing"
>
{{ cldrConstants.VOTE_FOR_MISSING }} - vote for missing
</button>
<a-button type="cancel" @click="onCancel">Cancel</a-button>
<a-button type="primary" @click="onSubmit">Submit</a-button>
</div>
</a-modal>
</template>

<style scoped>
.button-container {
display: flex;
Expand Down
Loading
Loading